在我的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]]
)
(:require
[testlib.core :refer [var1 var2]]))
(defn getValues [^String]
(java.util.ArrayList. [3 5]))
如果我在import
项目中的另一个命名空间内尝试testlib
此类(在调用compile
之后),我可以无错误地调用getValues
方法。
但是,如果我lein install
,请在另一个项目testlib
中加入jartest
,然后在下面的测试名称空间中使用它
(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
但是,如果我从上面的require
命名空间定义中删除NewClass
,则代码甚至可以在另一个库中运行。所以问题是由一些缺少的依赖项引起的,尽管我确保testlib
中的所有依赖项也包含在jartest
中,并且testlib.core
名称空间是AOT编译的。
另外,我已经尝试反编译生成的com.some_long_path.NewClass
类文件,并且有一个静态初始化程序块,如下所示:
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
很可能上述错误是从loadWithClass
内引发的。但我怎么知道到底出了什么问题呢?
谢谢!
更新:我能够通过二进制搜索错误找出我需要的命名空间中的错误(注释掉代码直到事情再次起作用)。事实证明,slurp
中的resources
文件夹中的某些文件是testlib
,但jartest
项目中没有这些文件。更改代码以使用clojure.java.io/resource
解决了问题。然而,问题仍然存在 - 如何在不诉诸蛮力方法的情况下确切地找出问题所在?
答案 0 :(得分:1)
这是必须的答案 - 没有更好的方法,没有更深入地理解依赖树,这通常只能通过评论东西并看到现在有效的方式来完成。这是我从clojure和使用gen-class进行java类加载的经验。
Heres希望这不是最高投票的答案。