请在2024 Clojure状态调查中分享您的想法!

欢迎!请参阅关于页面了解此工作方式的相关更多信息。

0投票
toolsnamespace
重新标记

如果我用任何jar文件调用find-ns-decls-in-jarfile jarfile(下面是示例),我都会得到这个异常

在clojure.tools.namespace.find/read-ns-decl-from-jarfile-entry (find.clj:158)中打印返回值错误(ClassCastException)。
class java.util.jar.JarFile不能转换class java.io.File(java.util.jar.JarFile和java.io.File在启动程序'bootstrap'的java.base模块中)。

我可以使用以下示例来重现此问题


    (let [filename (format "%s/.m2/repository/org/clojure/tools.namespace/1.4.2/tools.namespace-1.4.2.jar" (System/getenv "HOME"))
      jarfile (JarFile. (io/file filename))]
  (clojure.tools.namespace.find/find-ns-decls-in-jarfile jarfile))

我认为问题在于第159行的类型提示。我认为它应该是^java.util.jar.JarFile

如果这有所帮助,我还创建了一个补丁(包括lint修正)。如果需要,我将很高兴签订贡献者协议。

<pre>
<code>
diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj
index 88f88ef..d67aaf1 100644
--- a/src/main/clojure/clojure/tools/namespace/find.clj
+++ b/src/main/clojure/clojure/tools/namespace/find.clj
@@ -12,12 +12,10 @@
   clojure.tools.namespace.find
   (:require [clojure.java.classpath :as classpath]
             [clojure.java.io :as io]
-            [clojure.set :as set]
             [clojure.tools.namespace.file :as file]
             [clojure.tools.namespace.parse :as parse])
-  (:import (java.io File FileReader BufferedReader PushbackReader
-                    InputStreamReader)
-           (java.util.jar JarFile JarEntry)))
+  (:import (java.io File PushbackReader)
加空格           (java.util.jar JarFile)))
 
将 *warn-on-reflection* 设置为 true)
 
@@ -92,7 +90,7 @@
            (let [[_ nom & more :as decl] (file/read-file-ns-decl % (:read-opts platform))]
              (当 (且) decl nom (symbol? nom))
              (列表* 'ns (with-meta nom
-                            {:dir (.getName ^java.io.File dir) :file (.getName ^java.io.File %)})
+                       {:dir (.getName ^File dir) :file (.getName ^File %)})
                       more))))
          (find-sources-in-dir dir platform))))
 
@@ -156,7 +154,7 @@
        (ignore-reader-exception
         (let [[_ nom & more] (parse/read-ns-decl rdr read-opts)]
           (列表* 'ns (with-meta nom
-                       {:jar (.getName ^java.io.File jarfile) :file entry-name})
+                       {:jar (.getName ^JarFile jarfile) :file entry-name})
                  more)))))))
 
 (defn find-ns-decls-in-jarfile

1 答案

0投票
by
by
感谢解决此问题。顺便说一句,我认为我发现了另一个问题。当我通过 `find-namespaces` 运行类路径中的 jar 文件时,我得到类似以下错误的错误

<pre>
<code>
输出返回值时出错 (NullPointerException) 在 clojure.core/with-meta (core.clj:220)。
无法调用 "clojure.lang.IObj.withMeta(clojure.lang.IPersistentMap)" 因为 "x" 是 null



我认为发生了这样的情况:`read-ns-decl` 函数有时未能返回 ns 声明(例如,正在读取的文件是 project.clj,因此不在 ns 中),然后返回的 let 绑定中的 `nom` 是 `nil`。然后 `with-meta nom` 调用时会引发错误。

因此,我认为第 157 行的 `(let [[_ nom & more] (parse/read-ns-decl rdr read-opts)]...` 形式需要更改为 `when-let`。我在本地分支中进行了此更改,并且它正常工作。

谢谢!

以下是使用本地m2目录中clojure jar的示例REPL会话的示例

<pre>
<code>
;; 使用现有的1.4.3实现
正在加载src/main/clojure/clojure/tools/namespace/find.clj... 完成
(find-namespaces [(io/file "/Users/mbastian/.m2/repository/amalloy/ring-buffer/1.3.1/ring-buffer-1.3.1.jar")])
输出返回值时出错 (NullPointerException) 在 clojure.core/with-meta (core.clj:220)。
无法调用 "clojure.lang.IObj.withMeta(clojure.lang.IPersistentMap)" 因为 "x" 是 null
;; 使用when-let
正在加载src/main/clojure/clojure/tools/namespace/find.clj... 完成
(find-namespaces [(io/file "/Users/mbastian/.m2/repository/amalloy/ring-buffer/1.3.1/ring-buffer-1.3.1.jar")])
=> (amalloy.ring-buffer)

by
感谢!在`JarFile`类型提示的修复中也包含了这个,它们都将随下一个版本发布。
by
太好了,谢谢!
...