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

欢迎!请查看关于页面获取更多关于如何使用本网站的说明。

0
tools(namespace)
重命名标签

当我调用 find-ns-decls-in-jarfile jarfile (以下为示例) 时,无论使用哪个 jar 文件都会出现异常

在 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

如果需要,我还创建了一个以下补丁(包括代码风格修复)。如果需要,我很乐意签署贡献者协议。

<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)))
导入 Java.io.File 和 PushbackReader(java.io.File PushbackReader)。
导入 java.util.jar.JarFile)。
 
将 *warn-on-reflection* 设置为 true)。
 
@@ -92,7 +90,7 @@
          (将文件/读取文件-命名空间声明% %(:读选项平台)分解成[[_ nom & & more] :as decl])
            (当且仅当 decl、nom 和 nom 为符号时)
              将(list* '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 @@
        (忽略读取器异常
         将[ _ nom & & more] (解析/读取命名空间声明rdr read-opts)分解成[[_ nom & & more]])
           (将(list* '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
< code
< pre

< span itemprop = "answerCount " > 1 答案

0
< span class = "qa-a-item-avatar " > < a href = “../../index.php/user/Fogus” class = "qa-avatar-link “> < img src = “../../?qa = image & amp; qa_blobid = 9809168752875630459 & amp; qa_size = 40” width = “40” height = “40” class = "qa-avatar-image " alt = “” > < span class = "qa-a-item-meta " > < a href = “../../index.php/12732/clojure-tools-namespace-throws-casting-error-calling-jarfile?show=12751 #a12751” class = "qa-a-item-what " itemprop = "url " > 回答了 < span class = "qa-a-item-when " > < span class = "qa-a-item-when-data " > < time itemprop = "dateCreated " datetime = " 2023-03-10T16:36:22 +0000 " title = " 2023-03-10T16:36:22 +0000 " > Mar 10, 2023 < span class = "qa-a-item-who " > < span class = "qa-a-item-who-pad " > 通过 < span class = "qa-a-item-who-data " > < span itemprop = "author " itemscope = "" itemtype = " https://schema.org/Person " > < a href = “../../index.php/user/Fogus” class = "qa-user-link " itemprop = "url " > < span itemprop = "name " > Fogus
< span class = "qa-c-item-avatar " > < a href = “../../index.php/user/Mark+Bastian” class = "qa-avatar-link “> < img src = “../../?qa = image & amp; qa_blobid = 8932661785429763249 & amp; qa_size = 20” width = “20” height = “20” class = "qa-avatar-image " alt = “” > < span class = "qa-c-item-meta " > < a href = “../../index.php/12732/clojure-tools-namespace-throws-casting-error-calling-jarfile?show=12761 #c12761” class = "qa-c-item-what " itemprop = "url " > 评论了 < span class = "qa-c-item-when " > < span class = "qa-c-item-when-data " > < time itemprop = "dateCreated " datetime = " 2023-03-13T19:46:26 +0000 " title = " 2023-03-13T19:46:26 +0000 " > Mar 13, 2023 < span class = "qa-c-item-who " > < span class = "qa-c-item-who-pad " > 通过 < span class = "qa-c-item-who-data " > < span itemprop = "author " itemscope = "" itemtype = " https://schema.org/Person " > < a href = “../../index.php/user/Mark+Bastian” class = "qa-user-link " itemprop = "url " > < span itemprop = "name " > Mark Bastian
谢谢解决这个问题。顺便说一句,我想我已经发现另一个问题。如果我在我的类路径上运行 jars,并通过 `find-namespaces` 得到类似于以下错误:

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

我想发生的事情是 `read-ns-decl` 函数有时无法返回一个 ns 声明(例如,读取的是 project.clj,因此不在 ns 中)并且 nom 在返回的 let 绑定中是 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")])
在 clojure.core/with-meta (core.clj:220) 打印返回值时出错 (NullPointerException)。
不能调用 "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)
< code
< pre
by
谢谢!我也在修复 `JarFile` 类型提示的补丁中处理了这个问题,它们将随着下一个版本一起发布。
by
太好了,谢谢!
...