在Java中有一个simple way来获取正在运行的jar文件的路径:
MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()
但在Clojure中,我们没有类名,只有名称空间和函数。同样的事情适用于未编译的脚本/ REPL。
所以我的问题是:
答案 0 :(得分:8)
默认情况下,类的名称是AOT编译的命名空间的名称(这是gen-class的用途),因此您只需使用命名空间的类。
(ns foo.core
(:gen-class))
(defn this-jar
"utility function to get the name of jar in which this function is invoked"
[& [ns]]
;; The .toURI step is vital to avoid problems with special characters,
;; including spaces and pluses.
;; Source: https://stackoverflow.com/q/320542/7012#comment18478290_320595
(-> (or ns (class *ns*))
.getProtectionDomain .getCodeSource .getLocation .toURI .getPath))
(defn -main [& _]
(println (this-jar foo.core)))
跑步结果:
$ java -cp foo-0.1.0-SNAPSHOT-standalone.jar foo.core
/home/rlevy/prj/foo/target/foo-0.1.0-SNAPSHOT-standalone.jar
答案 1 :(得分:2)
classpath的想法是隐藏类的来源。您可能从不同的类加载器中加载了具有相同名称的类,您可能在多个jar中具有相同的类,并依赖类路径排序来选择正确的类。
你为什么想知道?如果出于调试/记录目的之外的任何其他原因,您处于危险的境地并应谨慎行事。
事实上,没有jar文件的类是完全合理的。对于任何运行时生成的类(思考代理),这可能发生在java中。
在clojure中,一个简单的例子如下面的repl会话所示......你会看到@mikera的建议适用于clojure.lang.Atom
这是一个内置类。但是当你使用deftype
创建自己的类型时,clojure会生成一个类,它没有位置......
user> (prn (-> clojure.lang.Atom
(.getProtectionDomain)
(.getCodeSource)
(.getLocation)))
#<URL file:/workspace/clj-scratch/lib/clojure-1.3.0.jar>
nil
user> (deftype Foo [])
user.Foo
user> (prn (-> (Foo.)
(.getClass)
(.getProtectionDomain)
(.getCodeSource)
(.getLocation)))
nil
nil
user>
答案 2 :(得分:1)
我没试过这个,但看起来你需要的只是一个类实例。例如,你可以不这样做:
(-> (new Object) (.getClass) (.getProtectionDomain) (.getCodeSource) (.getLocation) (.getPath))
答案 3 :(得分:1)
您可以尝试从Clojure本身定义的类中获取路径,例如:
(-> clojure.lang.Atom (.getProtectionDomain) (.getCodeSource) (.getLocation))
=> file:/some/path/to/clojure-1.3.0.jar
我相信如果您在REPL上运行Clojure脚本或编码,这在技术上就是正在运行的jar文件。
答案 4 :(得分:1)
(defn this-jar
"utility function to get the name of jar in which this function is invoked"
[& [ns]]
(-> (or ns (class *ns*))
.getProtectionDomain .getCodeSource .getLocation .toURI .getPath))
请注意,调用.toURI
以避免出现具有空格的路径问题至关重要,如同等Java问题中所述:How to get the path of a running JAR file?。
答案 5 :(得分:0)
在jar中查找源文件:tools.namespace/clojure-sources-in-jar