I'd like to have two main classes (or more) with leiningen, and then be able to choose which one at the java command line. For example I have:
(ns abc (:gen-class))
(defn -main [] (println "abc"))
(ns def (:gen-class))
(defn -main [] (println "def"))
With a project.clj having:
(defproject my-jar "0.0.1"
:description "test"
:dependencies [
]
:main abc)
Then I build with lein uberjar
, and run:
java -cp my-jar-0.0.1-standalone.jar abc
java -cp my-jar-0.0.1-standalone.jar def
I get it that when I specified :main abc
in the project.clj it was calling that out as the main-class in the manifest, but I couldn't get it to run without putting something. But either way when I try to run the 'def' main, I get a class not found:
Exception in thread "main" java.lang.NoClassDefFoundError: def
This works at least with leiningen 2.0+
Then you can run each main like so:
Which expands to this:
I'm using this in one of my projects and it works perfectly.
What worked for me in both lein 2.7.0's run task as well as from the resulting uberjar is as follows...
project.clj:
For source like...
This lets lein run work like...
From the command line the '-' in many-mains needs to become a '_' which makes it a legal Java classname.
There seems to have been some behavior changes between Lein 2.7.0 and prior around the effect of :main nil on the MANIFEST.MF. What I've got here works like a champ in Lein 2.7.0. The full source is at https://github.com/robertkuhar/many-mains
I added
:aot [abc def]
to the project.clj to generate compiled code and it worked.