【问题标题】:Getting Runtime Access to Clojure version number获取 Clojure 版本号的运行时访问权限
【发布时间】:2013-06-11 15:53:25
【问题描述】:

so question 我开发了下面的代码。目前,它的唯一目的(编译为 uberjar)是打印其版本号并退出。

; core.clj

(ns clojure-test-vnum.core
   (:gen-class))

(defn implementation-version []
  (-> (eval 'clojure-test-vnum.core) .getPackage .getImplementationVersion))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  ;; work around dangerous default behaviour in Clojure
  (alter-var-root #'*read-eval* (constantly false))

  (println (implementation-version)))



  ;project.clj

  (def version "0.1.0-SNAPSHOT")

  (defproject clojure-test-vnum version
     :manifest {"Implementation-Version" ~version}
     :description "Test to see if I can get a version number from an uberjar." 
     :url "http://example.com/FIXME"
     :license {:name "Eclipse Public License"
     :url "http://www.eclipse.org/legal/epl-v10.html"}
     :dependencies [[org.clojure/clojure "1.5.1"]]
     :main clojure-test-vnum.core
     :aot [clojure-test-vnum.core])

虽然这段代码编译得很好,但我在运行时收到了 ClassNotFoundException。问题似乎出在 (eval 'clojure-test-vnum.core)

以下是完整的堆栈跟踪:

  Exception in thread "main" java.lang.ClassNotFoundException: clojure-test-vnum.core, compiling:(NO_SOURCE_PATH:0:0)
     at clojure.lang.Compiler.analyze(Compiler.java:6380)
     at clojure.lang.Compiler.analyze(Compiler.java:6322)
     at clojure.lang.Compiler.eval(Compiler.java:6623)
     at clojure.lang.Compiler.eval(Compiler.java:6582)
     at clojure.core$eval.invoke(core.clj:2852)
     at clojure_test_vnum.core$implementation_version.invoke(core.clj:5)
     at clojure_test_vnum.core$_main.doInvoke(core.clj:14)
     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 clojure_test_vnum.core.main(Unknown Source)
 Caused by: java.lang.ClassNotFoundException: clojure-test-vnum.core
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:61)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:266)
    at clojure.lang.RT.classForName(RT.java:2070)
    at clojure.lang.Compiler.resolveIn(Compiler.java:6855)
    at clojure.lang.Compiler.resolve(Compiler.java:6818)
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6779)
    at clojure.lang.Compiler.analyze(Compiler.java:6343)
    ... 10 more

我做错了什么?

【问题讨论】:

    标签: jar clojure manifest


    【解决方案1】:

    你需要改变

    (eval 'clojure-test-vnum.core)
    

    clojure_test_vnum.core
    

    因为生成的类将在其名称中使用下划线代替它所基于的 Clojure 实体名称中的连字符。不需要eval,符号将简单地解析为类。

    【讨论】:

    • 非常感谢您的回答。我现在知道如何从 uberjar 打印版本号。然而,需要注意的一件事是 eval 确实似乎是必要的。如果不使用 eval 会引发异常(在类名前加或不加 ' 前缀)。我也觉得有必要这样做很奇怪。
    • @satch5150:我已经用答案中建议的修正测试了你的代码,它工作正常。请注意,您也必须省略符号前面的引号 (')。 (否则,您将尝试在符号上调用 getPackage,而不是它解析为的类。)
    猜你喜欢
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 2017-09-24
    • 1970-01-01
    • 2015-08-22
    相关资源
    最近更新 更多