举例说明:clojure/tools.logging。
重现步骤
- 静态编译 clojure/tools.logging (clojure.tools.logging 和 clojure.tools.logging.impl) 中所有的命名空间。
- 将结果放在类路径上,然后静态编译 clojure/java.data (clojure.java.data)。
- 在第二次编译的输出中观察 clojure/tools/logging$eval32$fn__33.class
(确保为两次编译使用不同的输出目录)。
这通常是无害的,但如果尝试缓存静态编译输出,则可能成为问题。当以这种方式尝试缓存之前的静态编译运行时,有时会导致两个无关的命名空间生成相同的文件名。如果它们具有相同的内部表示,那就没问题,但无法保证它们具有相同的内部表示(因为 32 和 33 都是 (gensym))。这取决于类路径中哪个占上风,可能会导致严重问题。
我不是这方面的专家,但最好这些“额外”文件是作为 tools.logging 的一部分生成,或者以某种方式别名到它们编译的命名空间中(例如 clojure/java/data/$clojure$tools$logging$eval32$fn__33.class 或 clojure/tools/logging/$clojure$java$data$eval32$fn_33.class)。