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

我可以在clojure-maven-plugin的所有版本以及java.classpath的所有版本上确认这种行为。

从clojure-maven-plugin的1.3.13版本开始,不再使用{{-cp}}在命令行中指定Java类路径,而是生成一个包含真实classpath的manifest文件的临时JAR文件,然后用{{-jar}}启动Java。

请参阅clojure-maven-plugin(链接:[pull request #58](https://github.com/talios/clojure-maven-plugin/pull/58) 文本:pull request #58)包含的内容(链接:[commit 8d8e90e4](https://github.com/talios/clojure-maven-plugin/commit/8d8e90e41806a6927c11347e6fc13344ba53c887) 文本:commit 8d8e90e4)。

{{clojure.java.classpath/classpath}} 查看加载Clojure的类加载器,在这种情况下,是{{sun.misc.Launcher$AppClassLoader}}的子类加载器。AppClassLoader是(链接:[URLClassLoader](http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html) 文本:URLClassLoader)的子类,但其(链接:[getURLs()](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-plungin和clojure.java.classpath共同实施的正确/期望行为吗?

因此,我一直在检查jar文件(尽管我意识到我认为我并没有检查嵌套的jar文件——类加载器会检查嵌套文件吗?),现在您说还有一个第三个情况我需要考虑,对吗?清单文件?clojure.java.classpath中有没有用于读取它们的实用方法?

我正在使用这样的代码来识别类路径上的所有可用内容

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

谢谢,
Kevin

0 投票

评论人:stuart.sierra

目前,clojure.java.classpath既不处理JAR清单文件,也不处理嵌套的JAR文件。正如我在之前的评论中所描述的,这将很困难,并且短时间内不太可能成为我的优先事项。但我愿意审阅添加此功能的补丁,但必须证明它能够防止递归循环。

根据我对(链接:[JAR文件规范](http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html) 文本:JAR File Specification)的阅读,clojure-maven-plugin的行为可能会被视为与JAR规范的意图不符,该规范以这种方式描述了“Class-Path”清单属性

{quote}
"类路径:此属性值的指定是扩展库或此应用程序或扩展需要的 相对 URL。"( emphasis added)
{quote}

clojure-maven-plugin 正在创建一个包含 绝对 URL 的 JAR 清单,这些 URL 指向其他 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(由 alex+import 报告)
...