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

欢迎!请参阅关于页面以了解更多关于如何使用本站的信息。

+1
tools.deps

当需要在Windows上执行{{clojure}}时的类路径足够大时,它可能会超过单个命令行参数的最大大小,从而导致错误{{'java.exe'程序无法运行:文件名或扩展名太长}}。

关于这个问题的一些背景信息可以在https://github.com/ajoberstar/ClojureTools/issues/2和其它相关工单中找到。这实际上是Windows下基于JVM的开发中相当常见的问题,例如在(link: https://github.com/bazelbuild/bazel/issues/2242 text: Bazel)和(link: https://tuhrig.de/gradles-bootrun-and-windows-command-length-limit/ text: gradle)中。

一般情况下,解决方案是创建一个“路径jar” - 一个在它的MANIFEST.MF中有 {{Class-Path:}}条目的jar文件,没有任何其它内容。然后可以通过{{java ... -classpath pathing.jar clojure.main}}的方式来调用Java。

最近我想起来,这个“路径jar”可以看作是当前在\~/.cpcache/<hash>.cp文件中的同样信息,但是格式化为jar文件,而不是文本文件。因此,我建议如果Windows下的类路径过长,Clojure代码中的{{make-classpath}}应该输出一个包含这些信息的文件~/.cpcache/<hash>.jar。然后在PowerShell的一侧,主{{clojure}}函数可以检查这个文件的存在,如果存在,则调用java -cp \~/.cpcache/<hash>.jar clojure.main(而不是当前使用<hash>.cp内容的做法)。

我认为我应该可以为此提供一个补丁。我在PowerShell的一侧对此稍作了一些实验,具体细节可以在上面ClojureTools工单链接的pull request中看到,生成实际jar文件的代码相当简单 - 一点字符串转换和调用{{jar cfm path.jar manifest.txt}}即可,这可能从JVM的一侧来看并不是必需的。

8个回答

0

评论由:timgilbert

所以,{{0001-Adding-cp-jar-argument.patch}} 添加了一个命令行标志({-cp-jar})到 tools.deps 中的 {{make-classpath}} 部分。当此文件存在时,tools.deps 会通过将类路径转换为空格分隔的 {{file://}} URL 列表,将其放入 jar 清单中,并创建一个只包含清单的 jar 文件,从而生成上述路径的 jar。这段代码最终比我想的要简单。

这还需要另一段代码才能正确工作 - 当 {{brew-install}} 或 Windows 等效脚本在构建路径时,需要将此标志传递给 make-classpath 脚本,然后调用 {{java -cp .cpcache/1864468523.jar clojure.main}} 以实际启动 clojure。

我已经在 Windows 的 powershell 和 WSL(即 Linux)中测试过此代码,通过在 repl 中调用 {{(write-pathing-jar "path.jar" (slurp cached-cp-filename))}}。之后,我能够通过 {{java -cp path.jar clojure.main}} 执行 Clojure 以启动 REPL,然后在该 REPL 内部调用 {{(require 'clojure.tools.deps.alpha.script.make-classpath)}} 以验证我是否可以引入本地命名空间。

0

评论由:timgilbert

我向 aoberstar 的 ClojureTools 仓库提交了一个 PR,实现了 PowerShell 这一边,这个补丁和这个补丁的组合解决了我遇到的类路径问题。

https://github.com/ajoberstar/ClojureTools/pull/5

0

评论由:alexmiller

ajoberstar 仓库中的所有内容都已合并到主仓库中(还包括更多工作),因此最好在 https://github.com/clojure/brew-install/tree/1.10.0 上构建补丁。

0

评论由:timgilbert

哦,太酷了。我会针对那个生成另一个补丁并将其附加到此事务上。

0

评论由:alexmiller

顺便说一句,如果你在一个 github PR 中,只需在 url 末尾添加 .patch,就可以获得补丁文件。

0

评论由:timgilbert

哦,上面的 {{0002-Calling-cp-jar-to-create-pathing-jar.patch}} 是 brew-install 的补丁,也在 github 上,链接为 https://github.com/clojure/brew-install/pull/4

0

评论由:timgilbert

哎呀!这个更新的 0002 补丁修复了之前 brew-install 补丁中围绕 {{$ForceCP}} 的语法错误。

0
参考: https://clojure.atlassian.net/browse/TDEPS-120(由 timgilbert 报告)
...