2024 年 Clojure 调查! 中分享您的想法。

欢迎!请参阅 关于 页面,获取更多有关该功能的详细信息。

0
java.classpath

我有一个项目存储在 resources 中的数据,它期望在类路径上找到这些数据。当项目使用 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 类路径,而是生成一个包含真实类路径的清单文件的临时 JAR 文件,并使用 {{-jar}} 启动 Java。

请参阅clojure-maven-plugin(链接:[https://github.com/talios/clojure-maven-plugin/pull/58](https://github.com/talios/clojure-maven-plugin/pull/58) 文本:拉取请求#58)包含(链接:[https://github.com/talios/clojure-maven-plugin/commit/8d8e90e41806a6927c11347e6fc13344ba53c887](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](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()](http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html#getURLs()) 文本:getURLs)方法仅返回JAR文件的URL。没有明显的方法获取清单文件中{{Class-Path}}属性的值,而不需要打开和读取JAR文件的正文。

0

评论由:stuart.sierra 提供

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

0

评论由:drlivingston 提供

感谢您关注此事。
我是否理解这是一起使用clojure-maven-plungin和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](http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html) 文本:JAR文件规范)的阅读,clojure-maven-plugin的行为可以被认为违反了JAR规范的宗旨,该规范将“Class-Path”清单属性描述如下

{引用}
"Class-Path: 此属性的值指定了该应用程序或扩展需要使用的扩展或库的**相对URL**"(强调已添加)
{引用}

clojure-maven-plugin正在创建一个包含指向其他JAR文件的“Class-Path”属性的JAR清单,这些URL是绝对路径,而这些JAR文件并非嵌入到包含清单的JAR中。

我一直认为,具有Class-Path属性的JAR清单文件仅在打包完整的应用程序或JDK扩展时使用,而不是在开发过程中指定类路径的一种机制。显然,这是可能的,就像当前的clojure-maven-plugin所展示的那样,但这并不是我愿意依赖的功能。

一般来说,JDK不支持列出classpath上的所有文件,因为classpath可以包含指向远程资源的URL,这些资源在需要时下载。

0

评论由:drlivingston 提供

有趣的。我没有意识到这些功能如此灵活。
感谢你的评论。

所以,在CP上递归迭代看起来可能是一件坏事,尽管我想这并不比你刚好需要在CP最深入的最后一个角落中找到的东西要糟糕,对吧?

我一直在把资源文件放在CP上,然后应用程序通过它们名称的前缀来找到它们。例如,查找所有的"foo.bar"并得到"foo.bar.baz1"和"foo.bar.baz2"等,而无需应用程序知道有哪些或需要生成或维护清单。这被认为是处理classpath上资源的一种已知反模式吗?

0

评论由:stuart.sierra 提供

{引用}
这被认为是处理classpath上资源的一种已知反模式吗?
{引用}

是的。

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