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
by

评论者:martinraison

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

0
by

评论者:panewman

我用13个模式尝试过clojure.core.match,但在Windows下编译失败。我认为这是问题的根源。

0
by

评论者:chrisbetz

这一点的一些信息

我的一个同事遇到了这个问题,因为他正在使用Linux / eCryptfs(与通常使用的FileVault加密的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=melriefhttps://issues.scala-lang.org/browse/SI-3623?focusedCommentId=76104&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-76104

使用未加密的文件系统临时存储类文件,例如通过具有tempFS将内容保存在内存中。这不是最好的方法,因为我们不喜欢留下重要内容未加密...

0
by

评论者:alexvong1995

你好,

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

我认为解决这个问题的方法之一是提供一个选项,将类文件作为jar包装,并使用较短的文件名,这样类名就可以保持不变(zip文件的名称可以无限长,对吧?)。你怎么看?

顺便说一句,我正在使用clojure 1.9.0,所以我认为我们应该说这个漏洞也影响1.9。

0

评论者:alexvong1995

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

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

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

0

评论者:alexmiller

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

0

评论者:[email protected]

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

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

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

`

这样,{{(trampoline (nestfn 10 "foo"))}} 就会返回 "foo"。然而,我在macOS上n=1000时得到了 CompilerException java.lang.StackOverflowError。

0

评论者:gsnewmark

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

0
评论人:alexmiller

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