5

だから私は現在このコードを持っています:

(ns contact-form.core
  (:gen-class))

(def foo "Hello World!")

(defn some-func [a-symbol]
  (println (str a-symbol "'s value is: " (eval a-symbol))))

(defn -main [& args]
  (some-func 'foo))

Emacs で行った後C-c C-k、次の出力が得られます。

contact-form.core> (-main)
foo's value is: Hello World!
nil

しかしlein uberjar、結果のjarファイルを実行して実行すると、エラーが発生します:

Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)
    at clojure.lang.Compiler.analyze(Compiler.java:6235)
    at clojure.lang.Compiler.analyze(Compiler.java:6177)
    at clojure.lang.Compiler.eval(Compiler.java:6469)
    at clojure.lang.Compiler.eval(Compiler.java:6431)
    at clojure.core$eval.invoke(core.clj:2795)
    at contact_form.core$some_func.invoke(core.clj:7)
    at contact_form.core$_main.doInvoke(core.clj:10)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at clojure.lang.AFn.applyToHelper(AFn.java:159)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at contact_form.core.main(Unknown Source)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: foo in this context
    at clojure.lang.Util.runtimeException(Util.java:156)
    at clojure.lang.Compiler.resolveIn(Compiler.java:6720)
    at clojure.lang.Compiler.resolve(Compiler.java:6664)
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6625)
    at clojure.lang.Compiler.analyze(Compiler.java:6198)
    ... 10 more

だから私は2つの質問があります:

  1. uberjar が REPL とまったく同じように機能しないのはなぜですか?
  2. この問題を解決するにはどうすればよいですか?
4

1 に答える 1

5

1. uberjar の機能が REPL と異なるのはなぜですか?

エラー「NO_SOURCE_PATH」の原因は、「foo.

説明すると、REPL でコードを評価して実行すると、 REPL によって評価されるcontact-form.coreため、期待どおりに名前空間に配置されますが、名前空間(ns contact-form.core)に切り替えてuser呼び出す-mainと、同じエラーが発生する可能性があります。

contact-form.core=> (-main)
foo's value is: Hello World!
nil
contact-form.core=> (ns user)
nil
user=> (contact-form.core/-main)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:120) 
user=> 

mainしたがって、スタンドアロンの uberjar 実行 (REPL の外部) のエントリ ポイントを指定すること(contact-form.core/-main)で、jar の既定の名前空間 ( ) が評価されていないclojure.coreため、呼び出しと同じになります。(ns contact-form.core結果:関数への完全修飾 (名前空間) パスを使用して実行できますが、現在の既定の名前空間では使用できるmainシンボルはありません。contact-form.core

2.修正

解決策は、最初に名前空間に明示的に切り替えることです。

(defn -main [& args]
  (use 'contact-form.core)
  (some-func 'foo))
于 2012-01-15T12:33:30.677 に答える