2012-06-13 17 views
13

Chciałbym mieć dwie główne klasy (lub więcej) z leiningen, a następnie być w stanie wybrać, który z nich w wierszu poleceń java. Na przykład mam:Leiningen z wieloma głównymi klasami

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

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

Mając na project.clj mający:

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

Potem budować z lein uberjar i uruchom:

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

Rozumiem, że kiedy podano :main abc w project.clj było to wywołanie jako główna klasa w manifeście, ale nie mogłem go uruchomić bez umieszczenia czegoś. Ale tak czy inaczej, gdy próbuję uruchomić „def” głównym, mam klasę, nie znaleziono:

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

dlaczego nie używać clojure cli https://github.com/clojure/tools.cli i przekazać argument wiersza cmd, aby wywołać każdą z różnych opcji? – locojay

+0

Ostatecznie była to tymczasowa sytuacja polegająca na wielokrotnym zasilaniu sieci (szybkie uruchomienie/testowanie). Ale nie wiedziałem o tools.cli, więc dziękuję za link. Jestem pewien, że wykorzystam to w przyszłości. – Kevin

Odpowiedz

9

dodałem :aot [abc def] do project.clj wygenerować kod skompilowany i to działało.

+1

Skąd to dodałeś? – Jackson

12

Działa to przynajmniej z 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"]}) 

Następnie można uruchomić każdy główny tak:

lein main-a 
lein main-b 

który rozszerza się do tego:

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

jestem używając tego w jednym z moich projektów i działa idealnie.

+1

Dzięki za wspaniałą odpowiedź. Mała sugestia: IMO, jest jaśniejsze, aby "uruchomić" w nazwie aliasu; na przykład 'lein run-main-a'. (Mówię to, ponieważ 'lein run' jest domyślnie dostarczony). –

1

Co pracował dla mnie zadanie działać zarówno Lein 2.7.0, jak również z otrzymaną uberjar jest następujący ...

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}}) 

Dla źródła jak ...

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

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

Ta praca pozwala uruchomić Lein jak ...

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

Z wiersza poleceń "-" w wielu sieciach musi stać się "_", co czyni go legalną nazwą klasy Java.

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

Wydaje się pewne zmiany zachowań między Lein 2.7.0 i przed całym efekt: główny zera na MANIFEST.MF. To, co tu mam, działa jak mistrz w Lein 2.7.0. Pełne źródło to https://github.com/robertkuhar/many-mains

Powiązane problemy