请在2024 Clojure状态调查!中分享您的想法。

欢迎!有关如何使用本站的信息,请参阅关于页面。

0 投票
java.classpath

我有一个项目,它将数据存储在它预期在classpath上找到的资源中。当项目使用java.classpath 0.2.2和clojure-maven-plugin 1.3.20+时,调用(java.classpath/classpath)会产生意想不到的结果 - 它显示了某些sun东西,但没有依赖,没有clojure,没有我的代码或资源。Clojure似乎仍然可以工作,只是调用classpath api时有问题。

比较

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

java.classpath 0.1.0和c-m-plugin 1.3.20可能会出现问题,有时仅在classpath上显示一个看似为空清单的单个项目。

在此转发到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

我可以确认java.classpath的 所有版本在clojure-maven-plugin 1.3.13和之后的所有版本的clojure-maven-plugin上都展现出这种行为。

从clojure-maven-plugin的1.3.13版本开始,插件不再通过命令行上的{{-cp}}指定Java类路径,而是创建一个包含真实类路径的manifest文件的临时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。在未打开和读取JAR文件内容的情况下,没有任何明显的API可以获取清单文件的{{Class-Path}}属性。

0 投票

评论者:stuart.sierra

在深入挖掘OpenJDK源代码后,发现URLClassLoader会延迟读取JAR清单文件,以按需加载类或资源。要查找可能由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 文件的 绝对 URL 的 JAR 清单,这些 JAR 文件 并未 嵌入包含清单的 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 报告)
...