请在2024 Cljure现状调查!中分享您的想法。

欢迎!请在关于页面查看更多关于如何使用本站的信息。

+6
编译器
编辑

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

(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

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

0

评论者:panewman

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

0

评论者:chrisbetz

还有关于这个问题的更多信息

我的一个同事遇到了这个问题,因为他正在使用Linux / eCryptfs(其中143的限额相对较小,与其他通常使用的FileVault加密macOS相比):见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

使用非加密的文件系统暂时存储class文件,也许可以通过tempFS将文件保存在内存中来做到这一点。这不是最好的方法,因为我们不喜欢留下未加密的重要文件...

0

评论者:alexvong1995

您好,

我在使用clojure.core.match时遇到了相同的问题。我宏展开函数定义,观察到宏展开后的定义非常深。

我认为解决这个问题的一种方法是为将类文件包装成jar文件(使用较短的文件名),这样类名就可以保持不变(压缩文件名可以任意长,对吧?)。您觉得怎么样?

顺便说一下,我正在使用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-like方法(如果 名称过长,则名称哈希)的补丁会被考虑吗?由于它打破了二进制兼容性,此漏洞默认情况下会被禁用,但可以使用新的编译器选项启用名称哈希。这种方法肯定有助于我们特定的案例,但我不确定它是否足够有用/通用,可以包含在编译器中,因此我尚未开始修补补丁。

0
by
_Comment made by: alexmiller_

不会做出任何破坏性更改。计划是在当前策略无效时切换第二个策略。
0
参考:[https://clojure.atlassian.net/browse/CLJ-1852](https://clojure.atlassian.net/browse/CLJ-1852)(由alex+import报告)
...