2012-06-13 5 views
13

Я хотел бы иметь два основных класса (или более) с leiningen, а затем иметь возможность выбрать, какой из них находится в командной строке java. Например, у меня есть:leiningen с несколькими основными классами

(ns abc (:gen-class)) 
(defn -main [] (println "abc")) 

(ns def (:gen-class)) 
(defn -main [] (println "def")) 

С project.clj, имеющий:

(defproject my-jar "0.0.1" 
:description "test" 
:dependencies [ 
] 
:main abc) 

Тогда я строю с lein uberjar и выполнить команду:

java -cp my-jar-0.0.1-standalone.jar abc 
java -cp my-jar-0.0.1-standalone.jar def 

Я понимаю, что, когда я указал :main abc в проекте.clj он называл это основным классом в манифесте, но я не мог заставить его работать, не помещая что-то. Но в любом случае, когда я пытаюсь запустить «Защиту» главный, я получаю класс не найден:

Exception in thread "main" java.lang.NoClassDefFoundError: def 
+0

Почему бы не использовать clojure cli https://github.com/clojure/tools.cli и передать аргумент строки cmd для вызова каждого из разных параметров? – locojay

+0

В конечном итоге это была временная ситуация, когда у вас было несколько сетей (быстрая разработка/тестирование). Но я не знал о tools.cli, поэтому спасибо за ссылку. Я уверен, что буду использовать его в будущем. – Kevin

ответ

9

Я добавил :aot [abc def] в project.clj для генерации скомпилированного кода, и она работала.

+1

Где вы добавляли? – Jackson

12

Это работает, по крайней мере с Leiningen 2.0+

(defproject my-jar "0.0.1" 
:description "test" 
:dependencies [ 
] 
:profiles {:main-a {:main abc} 
      {:main-b {:main def}} 
:aliases {"main-a" ["with-profile" "main-a" "run"] 
      "main-b" ["with-profile" "main-b" "run"]}) 

Затем вы можете запустить каждый основной так:

lein main-a 
lein main-b 

который расширяется к этому:

lein with-profile main-a run 
lein with-profile main-b run 

Я используя это в одном из моих проектов, и он отлично работает.

+1

Спасибо за отличный ответ. Небольшое предложение: IMO, более понятно, что он «работает» в псевдониме; например 'lein run-main-a'. (Я говорю это, потому что 'lein run' предоставляется по умолчанию.) –

1

То, что работало для меня в задаче выполняться как LEIN 2.7.0, а также из полученного в результате uberjar выглядит следующим образом ...

project.clj:

(defproject many-mains "0.1.0-SNAPSHOT" 
    :description "Project containing multiple main methods" 
    :dependencies [[org.clojure/clojure "1.8.0"]] 
    :main nil 
    :target-path "target/%s" 
    :profiles {:main-abc {:main many-mains.abc} 
      :main-def {:main many-mains.def} 
      :main-ghi {:main org.rekdev.mm.ghi} 
      :core {:main many-mains.core} 
      :uberjar {:aot :all}}) 

Для источника, как ...

$ cat src/many_mains/abc.clj 
(ns many-mains.abc 
    (:gen-class)) 

(defn -main 
    "" 
    [& args] 
    (println "Hello, from many-mains.abc!")) 

Это позволяет Lein запустить работу как ...

$ lein with-profile main-abc run 
Hello, from many-mains.abc! 

Из командной строки '-' во многих сетях необходимо стать '_', что делает его законным Java-классом.

$ java -cp target/uberjar/many-mains-0.1.0-SNAPSHOT-standalone.jar many_mains.abc 
Hello, from many-mains.abc! 

Там, кажется, произошли некоторые изменения в поведении между Lein 2.7.0 и до всего эффекта: основного ноля на MANIFEST.MF. То, что у меня здесь, работает как чемпион в Lein 2.7.0. Полный источник находится в https://github.com/robertkuhar/many-mains

Смежные вопросы