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: File name too long}}异常。

这个问题出奇地难以找到,可能是因为它没有提及或标记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(与我们的 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=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 文件,这样类名就可以保持不变(zip 文件名可以很长,对吧?)。你怎么看?

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

0

评论由:alexvong1995

我提出一个概念性补丁。如果类的名字长于255个字符,编译器现在输出jar文件而不是类文件。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一样的方法(如果名字太长则哈希名字)的补丁?这会破坏二进制兼容性,因此这个 workaround 默认会禁用,但可以通过使用新的编译器选项启用名称哈希。这种方法肯定会帮助我们的特定案例,但我不确定它是否足够有用/通用,可以包含在编译器中,所以我还没有开始编写补丁。

0
_评论者:alexmiller_

不会造成任何破坏性的更改。计划是在当前策略不起作用时切换到第二种策略。
0
参考:https://clojure.atlassian.net/browse/CLJ-1852(由 alex+import 报告)
...