[英]How to debug static initialiser errors in jars generated by Leiningen?
in my Clojure library testlib
, i've got a namespace with a :gen-class
directive that looks like this:在我的 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]))
If i try to import
this class inside another namespace in the testlib
project (after invoking compile
), i can invoke getValues
method without errors.如果我尝试在
testlib
项目的另一个命名空间中import
这个类(在调用compile
),我可以调用getValues
方法而不会出错。
However, if i lein install
, include testlib
in another project jartest
, and then use it in a test namespace below不过,如果我
lein install
,包括testlib
在另一个项目jartest
,然后在下面的测试命名空间使用
(ns jartest.core
(:import [com.some_long_path NewClass]))
(NewClass.)
(NewClass/getValues "some string")
invoking NewClass
constructor gives an exception调用
NewClass
构造函数会出现异常
CompilerException java.lang.NoClassDefFoundError: Could not initialize class com.some_long_path.NewClass
and getValues
as a consequence gives和
getValues
作为结果给出
CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'com.some_long_path.NewClass/getValues
However, if i remove the require
s from NewClass
namespace definition above, the code works even in another library.但是,如果我从上面的
NewClass
命名空间定义中删除require
,该代码甚至可以在另一个库中工作。 So the problem is caused by some missing dependencies, although i've made sure that all dependencies of testlib
are also included in jartest
, and that testlib.core
namespace is AOT-compiled.所以问题是由一些缺少的依赖项引起的,尽管我已经确保
testlib
所有依赖testlib
也包含在jartest
,并且testlib.core
命名空间是 AOT 编译的。
Also, i've tried decompiling generated com.some_long_path.NewClass
class file, and there is a static initializer block that looks like this:另外,我尝试反编译生成的
com.some_long_path.NewClass
类文件,并且有一个静态初始化块,如下所示:
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
Most probably the above-mentioned error is thrown from within loadWithClass
.很可能上述错误是从
loadWithClass
抛出的。 But how do i find out what exactly is wrong?但我如何找出到底是哪里出了问题?
Thanks!谢谢!
UPDATE: I was able to figure out what was wrong in the namespace i was requiring through a binary search for errors (commenting out code until things worked again).更新:我能够通过二进制搜索错误找出我需要的命名空间中有什么问题(注释掉代码,直到事情再次运行)。 It turned out that some files were
slurp
ed from resources
folder in testlib
, but they were not present in jartest
project.原来,一些文件被
slurp
编辑从resources
文件夹中testlib
,但他们并没有出现在jartest
项目。 Changing the code to use clojure.java.io/resource
fixed the problem.更改代码以使用
clojure.java.io/resource
解决了该问题。 However, the question still stands - how to find out exactly what was the problem, without resorting to brute force methods?然而,问题仍然存在 - 如何在不诉诸蛮力方法的情况下确切地找出问题所在?
Here is the obligatory answer- there isnt a better way, without understanding the dependency tree more deeply, which often can only be done by commenting stuff out and seeing what now works.这是强制性的答案 - 没有更好的方法,没有更深入地理解依赖树,这通常只能通过注释掉内容并查看现在有效的方法来完成。 That has been my experience with java classloading from clojure and using gen-class.
这是我从 clojure 加载 java 类和使用 gen-class 的经验。
Heres hoping this isnt the highest voted answer.继承人希望这不是最高投票的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.