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上的一个项目,看起来像是一个空的manifest。

在此处转发到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上确认此行为和java.classpath所有版本。

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

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

{{clojure.java.classpath/classpath}} 分析加载Clojure的类加载器,在这种情况下,它是一个 {{sun.misc.Launcher$AppClassLoader}} 的子类加载器。AppClassLoader 是 (链接:[URLClassLoader](http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html)) 的子类,但其 (链接:[getURLs()](http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html#getURLs())) 方法只返回 JAR 文件的 URL。没有显而易见的 API 来获取无打开和读取 JAR 文件内容的Manifest文件 {{Class-Path}} 属性。

0

由:stuart.sierra发表的评论

进一步挖掘 OpenJDK 的源代码时,URLClassLoader 会根据需要懒惰地读取 JAR 表明文件来加载类或资源。要找到 URLClassLoader 可能打开的所有 **URL** 列表,您必须重新实现此逻辑以读取所有表明文件。它也必须是递归的(JAR 表明引用了另一个具有表明的 JAR 文件)并检测循环。

0

由:drlivingston发表的评论

感谢您关注这个问题。
我理解这是 clojure-maven-plugin 和 clojure.java.classpath 共同行为的正确/期望行为吗?

所以,我在检查 JAR 文件,(尽管我意识到我可能没有检查嵌套的 JAR 文件 - 类加载器会检查嵌套文件吗?) 而您现在说还有一个第三种情况我需要覆盖,对吧?: Manifest 文件?clojure.java.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 Manifest 文件,也不处理嵌套 JAR 文件。正如我在之前的评论中所述,实现对此的支持将是困难的,并且在不久的将来不太可能成为我的优先事项。我愿意审阅添加此功能的补丁,但必须证明它能够防止递归循环。

根据我对 (链接:[JAR 文件规范](http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html)) 的理解,clojure-maven-plugin 的行为可以视为违反 JAR 规范的精神,该规范将 "Class-Path" manifest 属性描述如下:

{quote}
"Class-Path: 此属性的值指定了应用程序或扩展所需的库或扩展的 相对 URLs。"(强调已添加)
{quote}

clojure-maven-plugin 正在创建一个包含包含URL的 "Class-Path" 属性的 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](https://clojure.atlassian.net/browse/CLASSPATH-6)(由 alex+import 报告)
...