请分享您的想法,参加 2024 年 Clojure 状态调查!

欢迎!请参阅 关于 页面以获取更多关于如何使用本站的信息。

0
java.classpath

我在一个项目中存储数据在资源中,该项目期望在类路径上找到这些资源。当项目使用 java.classpath 0.2.2 和 clojure-maven-plugin 1.3.20+ 时,调用 (java.classpath/classpath) 产生意外结果 - 显示了某些 sun 东西,但没有依赖项,没有 clojure,也没有我的代码或资源。Clojure 似乎仍然在正常运行,只是调用类路径 API 时出现问题的调用。

比较

java.classpath 0.1.0 和 c-m-plugin 1.3.9 的行为符合预期。

java.classpath 0.1.0 和 c-m-plugin 1.3.20 可能会引发问题,有时仅显示类路径上的一个看似空清单的项目。

在此处跨帖子到 clojure-maven-plugin
https://github.com/talios/clojure-maven-plugin/issues/81

8 个回答

0

评论由:drlivingston 提出

也与这个 Java 版本一同出现
Java 版本:1.7.0_45,供应商:Oracle Corporation

0

评论由:stuart.sierra 提出

我可以在所有版本的 clojure-maven-plugin 1.3.13 以及更高版本上确认这种行为。

从 clojure-maven-plugin 1.3.13 版本开始,不再使用 {{-cp}} 在命令行上指定 Java 类路径,而是该插件生成一个包含实际类路径的清单文件的临时 JAR 文件,并使用 {{-jar}} 启动 Java。

请参见clojure-maven-plugin(链接:https://github.com/talios/clojure-maven-plugin/pull/58 文本:拉取请求#58)包含(链接:https://github.com/talios/clojure-maven-plugin/commit/8d8e90e41806a6927c11347e6fc13344ba53c887 文本:提交8d8e90e4)。

{{clojure.java.classpath/classpath}} 查看加载Clojure的类加载器,在这种情况下是{{sun.misc.Launcher$AppClassLoader}}的子类加载器。AppClassLoader是(链接:http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html 文本:URLClassLoader)的子类,但它的(链接:http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html#getURLs() 文本:getURLs)方法仅返回JAR文件的URL。没有明显的API可以在不打开和读取JAR文件内容的情况下获取清单文件(manifest file)的{{Class-Path}}属性。

0

评论由:stuart.sierra 提出

在进一步研究OpenJDK源代码时,发现URLClassLoader按需懒惰地读取JAR清单文件(manifest files),以加载类或资源。要找到URLClassLoader可能打开的所有URL的列表,就必须重新实现这个逻辑来读取所有的清单文件。这还必须递归(JAR清单引用了另一个带有清单的JAR文件)并检测循环。

0

评论由:drlivingston 提出

感谢您查看这些内容。
我理解这是clojure-maven-plugin和clojure.java.classpath共同完成正确的/期望的行为吗?

所以我开始进入jar文件中(尽管我已经意识到我不认为我在查看嵌套的jar文件 - 类加载器会查看嵌套文件吗?)现在您说的第三个情况我也必须考虑,对吗?清单文件?在clojure.java.classpath中有一个读取它们的实用方法吗?

我正在使用类似于下面的代码来确定classpath上可访问的内容

https://github.com/drlivingston/kr/blob/master/kr-core/src/main/clojure/edu/ucdenver/ccp/utils.clj#L101

谢谢,
凯文

0

评论由:stuart.sierra 提出

目前,clojure.java.classpath既不处理JAR清单文件,也不处理嵌套的JAR文件。正如我在之前评论中描述的,实现对此的支持将会很困难,而且在我短期内不太可能成为优先事项。我愿意审查添加此功能的补丁,但是它必须证明它可以防止递归循环。

根据我对(链接:http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html 文本:JAR文件规范)的阅读,clojure-maven-plugin的行为可以被视为违反了JAR规范的意图,该规范这样描述“Class-Path”清单属性:

{quote}
"Class-Path: 此属性的值指定了应用程序或扩展需要的扩展或库的相对URL。" (加粗为原文所加)
{quote}

clojure-maven-plugin正在创建一个包含指向其他JAR文件(这些JAR文件不包含在包含该清单的JAR中)的绝对URL的"Class-Path"属性的JAR清单。

我总是假设带有Class-Path属性的JAR清单文件仅在打包完整应用程序或JDK扩展时使用,而不是作为开发中指定类路径的机制。很明显,这是可能的,例如当前的clojure-maven-plugin所展示的,但这不是我想依赖的功能。

通常情况下,JDK不支持列举类路径上的所有文件,因为类路径可以包含指向远程资源的URL,这些资源将在需要时下载。

0

评论由:drlivingston 提出

挺有意思的。我没有意识到这些中有一些是如此灵活的。
谢谢你的评论。

所以递归迭代CP似乎可能是不好的事情,尽管我想这并不比要求加载一个刚好在CP最深处找到的东西更糟,对吧?

我将资源文件放在CP上,然后通过名称前缀来让应用程序找到它们。例如,查找所有"foo.bar"并得到"foo.bar.baz1"和"foo.bar.baz2"等。而不需要应用程序知道那里有什么,或者需要生成或维护清单。这是在类路径上处理资源的一个已知反模式吗?

0

评论由:stuart.sierra 提出

{quote}
这是在类路径上处理资源的一个已知反模式吗?
{quote}

是的。

0
参考:[https://clojure.atlassian.net/browse/CLASSPATH-6](https://clojure.atlassian.net/browse/CLASSPATH-6)(由alex+import报告)
...