Frage

Also habe ich derzeit diesen Code:

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

Nachdem ich in Emacs C-c C-k erstellt habe, erhalte ich die folgende Ausgabe:

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

Aber wenn ich lein uberjar mache und die resultierende JAR-Datei ausführe, erhalte ich eine Fehlermeldung:

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

Ich habe also zwei Fragen:

  1. Warum funktioniert das Uberjar nicht genau so wie das REPL?
  2. Was kann ich tun, um dieses Problem zu beheben?
War es hilfreich?

Lösung

1. Warum funktioniert Uberjar anders als REPL?

Eine Ursache für den Fehler "NO_SOURCE_PATH" ist, dass Sie sich derzeit nicht in dem Namespace befinden, der 'foo' definiert hat.

Zur Veranschaulichung: Wenn ich Ihren Code in meiner REPL auswerte und ausführe, wird er wie erwartet in den contact-form.core-Namespace eingefügt, da (ns contact-form.core) von der REPL ausgewertet wird. Wenn ich jedoch zum user-Namespace wechsle und -main aufrufe, kann ich dies tun den gleichen Fehler erzeugen:

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=> 

Wenn Sie also Ihren Einstiegspunkt für main für die eigenständige Ausführung von Uberjar (außerhalb der REPL) angeben, entspricht dies dem Aufruf von (contact-form.core/-main) aus dem Standard-Namespace in Ihrem Jar, der clojure.core ist, da (ns contact-form.core nicht ausgewertet wurde. Ergebnis: main kann mit einem vollständig qualifizierten (Namespace-) Pfad zur Funktion ausgeführt werden, aber keines der Symbole aus contact-form.core ist im aktuellen Standard-Namespace verfügbar.

2. Das Update

Die Lösung wäre, zuerst explizit zu Ihrem Namespace zu wechseln:

(defn -main [& args]
  (use 'contact-form.core)
  (some-func 'foo))

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top