在我的Clojure庫testlib
,我有一個:gen-class
指令看起來像這樣一個命名空間:如何調試Leiningen生成的jar中的靜態初始化錯誤?
(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
,包括在另一個項目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
類文件,並有一個靜態初始化塊,看起來像這樣:
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
最大的可能是上面提到的錯誤是從loadWithClass
中拋出。但是,我怎麼知道究竟是什麼錯誤?
謝謝!
更新:我能弄清楚我通過二進制搜索錯誤(註釋掉代碼,直到事情再次運行)所需的命名空間中出了什麼問題。原來,有些文件是slurp
ed 文件夾中的testlib
,但它們不存在於jartest
項目中。更改代碼以使用clojure.java.io/resource
解決了問題。然而,問題仍然存在 - 如何確切地找出問題所在,而不訴諸暴力手段?