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

欢迎!请访问 关于 页面获取更多关于如何使用本站的信息。

+6
编译器
编辑

Clojure 编译器生成的类名可以任意长,超过文件系统的最大允许文件名长度。例如,当您函数嵌套略深时就会发生这种情况

(defmacro nestfn [n & body]
  (if (> n 0)
    `(fn [] (nestfn ~(- n 1) ~@body))
    body))

(def myf (nestfn 100 "body"))

编译此代码会产生一个 {{java.io.IOException: 文件名过长}} 异常。

这个问题非常难以查找,可能是因为它没有提及,或标记为 core.match,尽管这是更常见的原因之一。

是否有所进展?该工单被标记为“关键”。
给它加上了标签。它不在我们的 1.12 的大纲上,但我已经将它列入 1.13 的研究名单。

10 个回答

0

评论者:martinraison

Scala 社区在一段时间前就发现了这个问题,现在编译器有一个 {{max-classfile-name}} 参数(默认值255)。当超过限制时,使用哈希。也许我们应该考虑类似的东西?

0

评论者:panewman

我尝试了使用 13 个样式的 clojure.core.match,在 Windows 下编译失败。我推测这是问题的根源。

0

评论者:chrisbetz

关于这个问题的更多信息

我的一个同事因为使用 Linux / eCryptfs(与我们的加密 macOS 相比,这个限制143相当小)遇到了这个问题:见https://bugs.launchpad.net/ecryptfs/ bug/344878

然而,Clojure 并非唯一遇到这个问题,Scala 也受到严重影响:https://issues.scala-lang.org/browse/SI-3623

没有“简单”的解决方案,显然,像 Scala 那样截断文件名会带来很多其他问题。

对于所有被这个问题困扰的人,一个可行的解决方案可能是 Mario Pastorelli 在 https://issues.scala-lang.org/secure/ViewProfile.jspa?name=melrief 中的评论 https://issues.scala-lang.org/browse/SI-3623?focusedCommentId=76104&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-76104 中提出的。

使用未加密的文件系统临时存储类文件,也许可以通过 tempFS 在内存中保存东西。这不是最好的方法,因为我们不喜欢留下未加密的重要信息...

0

评论者:alexvong1995

你好,

我使用 clojure.core.match 时遇到了相同的问题。我展开函数定义,并观察到宏展开的定义深度嵌套。

我认为解决这个问题的一种方法是为类文件提供一种打包为jar并使用较短文件名的选项,这样类名就可以保持不变(压缩文件的名称可以尽可能地长,对吧?)。你认为是这样吗?

顺便说一下,我使用的是clojure 1.9.0,所以我认为我们应该说这个漏洞也影响了1.9。

0
by

评论者:alexvong1995

我提出了一个概念验证补丁。编译器现在在类名长度超过255个字符时输出jar而不是class。jar名称只是类名的(左)截断。

假设**compile-path*设置为"build",那么您需要将build/添加到您的类路径中,以便找到jar文件。

这个补丁只是一个概念验证,理想情况下,应该将所有长名称类放入一个大的jar中,以避免解压缩多个文件。此外,用户应该能够指定**compile-name-max**和**compile-jar-name**。最后,代码相当丑陋,我应该将事情分割成几个函数。

0
by

由:alexmiller做出的评论

Alex - 我们不会输出jar。这与Clojure运行时的许多方面相抵触。

0
by

评论来自:[email protected]

如果这个评论离题了,请见谅。但是,原始示例对我来说有点令人困惑。也许它应该是这样的

`
(defmacro nestfn [n &.body]
(if (> n 0)

`(fn [] (nestfn ~(dec n) ~@body))
`(do ~@body)))

`

这样,{{(trampoline (nestfn 10 "foo"))}}将返回"foo"。然而,我在macOS上将n=1000时得到一个CompilationException java.lang.StackOverflowError。

0
by

评论来自:gsnewmark

@Alex Miller 你好!是否可以考虑一个类似Scala的补丁(如果名称太长则对名称进行哈希处理)?这种做法会破坏二进制兼容性,因此默认情况下一定会禁用这个 workaround,但可以通过使用新的编译器选项来启用名称哈希处理。这种方法肯定会有助于我们特定的情况,但我不确定它是否足够有用/通用,足以包含在编译器中,所以我还没有开始编写补丁。

0
评论人:alexmiller

不会引入任何重大变更。当当前策略无效时,应切换到第二个策略。
0
参考:https://clojure.atlassian.net/browse/CLJ-1852(由 alex+import 报告)
...