Clojure 如何调试Leiningen生成的JAR中的静态初始化器错误?
在我的Clojure库Clojure 如何调试Leiningen生成的JAR中的静态初始化器错误?,clojure,Clojure,在我的Clojure库testlib中,我有一个带有:gen class指令的名称空间,如下所示: (ns com.some_long_path.NewClass (:import (java.util List ArrayList)) (:gen-class :name com.some_long_path.NewClass :methods [^{:static true} [getValues [String] java.util.List]] ) (:
testlib
中,我有一个带有:gen class
指令的名称空间,如下所示:
(ns com.some_long_path.NewClass
(:import (java.util List ArrayList))
(:gen-class
:name com.some_long_path.NewClass
:methods [^{:static true} [getValues [String] java.util.List]]
)
(:require
[testlib.core :refer [var1 var2]]))
(defn getValues [^String]
(java.util.ArrayList. [3 5]))
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
如果我尝试在testlib
项目中的另一个名称空间中导入该类(在调用compile
之后),我可以调用getValues
方法而不会出错
但是,如果我lein install
,请在另一个项目jartest
中包含testlib
,然后在下面的测试命名空间中使用它
(ns jartest.core
(:import [com.some_long_path NewClass]))
(NewClass.)
(NewClass/getValues "some string")
调用NewClass
构造函数会产生异常
CompilerException java.lang.NoClassDefFoundError: Could not initialize class com.some_long_path.NewClass
和getValues
作为结果
CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'com.some_long_path.NewClass/getValues
但是,如果我从上面的NewClass
命名空间定义中删除require
s,代码甚至可以在另一个库中工作。因此,问题是由于缺少一些依赖项造成的,尽管我已经确保testlib
的所有依赖项也包含在jartest
中,并且testlib.core
命名空间是AOT编译的
此外,我还尝试反编译生成的com.some_long_path.NewClass
class文件,其中有一个静态初始化程序块,如下所示:
(ns com.some_long_path.NewClass
(:import (java.util List ArrayList))
(:gen-class
:name com.some_long_path.NewClass
:methods [^{:static true} [getValues [String] java.util.List]]
)
(:require
[testlib.core :refer [var1 var2]]))
(defn getValues [^String]
(java.util.ArrayList. [3 5]))
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
上述错误很可能是从loadWithClass
中抛出的。但我怎样才能找出到底是什么错呢
谢谢
更新:通过对错误进行二进制搜索(注释代码,直到一切恢复正常),我能够找出所需名称空间中的错误。事实证明,一些文件是从
testlib
中的resources
文件夹slurp
生成的,但它们不在jartest
项目中。将代码更改为使用clojure.java.io/resource
修复了该问题。然而,问题依然存在——如何在不诉诸暴力手段的情况下准确地找出问题所在?这是一个强制性的答案——没有更好的方法,不更深入地理解依赖关系树,这通常只能通过注释内容并查看现在的效果来完成。这就是我从clojure加载java类和使用gen类的经验
希望这不是投票率最高的答案