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

欢迎!请查阅关于页面,了解更多有关此处如何工作的信息。

0
java.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可能造成问题,有时类路径上只显示一个似乎是空清单的项目。

交叉发布到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 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。没有明显的API可以不打开和读取JAR文件内容就能获取清单文件的{{Class-Path}}属性。

0
by

评论由:stuart.sierra作出

进一步挖掘OpenJDK源代码,URLClassLoader会惰性读取JAR清单文件,这是在需要时加载类或资源的。要查找URLClassLoader可能打开的所有URL列表,您必须重新实现这个逻辑来读取所有的清单文件。这还必须递归(JAR清单引用了另一个包含清单的JAR),并检测循环。

0
by

评论由:drlivingston作出

感谢您查看这一问题。
我认为这是 clojure-maven-plugin 和 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

谢谢,
凯文

0
by

评论由:stuart.sierra作出

目前,clojure.java.classpath既没有处理JAR清单文件,也没有处理嵌套JAR文件。正如我之前所提到的,为其实现支持将是困难的,并且近期内不太可能成为我优先考虑的事项。我会愿意审阅添加此功能的补丁,但是它必须证明可以防止递归循环。

根据我阅读的《JAR 文件规范》(链接:http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html 文本),clojure-maven-plugin 的行为可能违背了 JAR 规范的精神,该规范对 “Class-Path” 清单属性描述如下

{quote}
"Class-Path: 这个属性值的用途是指定该应用程序或扩展所需的 相对 URL 。”(加粗内容为强调)
{quote}

clojure-maven-plugin 正在生成一个包含指向其他 JAR 文件的控制台文件(包含“Class-Path”属性的 JAR 文件)的控制台属性,这些其他 JAR 文件并未嵌入到包含控制台属性文件的 JAR 中。

我一直以来都认为,带有 Class-Path 属性的 JAR 清单文件仅在打包完整应用程序或 JDK 扩展时使用,而不是用来指定开发期间类路径的一种机制。显然这是可能的,正如当前 clojure-maven-plugin 所展示的那样,但这不是我想依赖的功能。

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

0
by

评论由:drlivingston作出

有趣。我没有意识到这部分如此灵活。
感谢您的评论。

所以,递归地对 CP 进行迭代似乎是个坏主意,尽管我想这可能比你要求加载放在 CP 末尾最深处的东西更糟,对吧?

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

0
by

评论由:stuart.sierra作出

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

是的。

0
by
参考: https://clojure.atlassian.net/browse/CLASSPATH-6(由 alex+import 提出)
...