2016-09-14 16 views
2

在我的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])) 

,如果我嘗試importtestlib項目的另一個命名空間裏這個類(調用compile後)我可以調用getValues方法沒有錯誤。

不過,如果我lein install,包括在另一個項目jartesttestlib,然後用它在測試的命名空間下面

(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解決了問題。然而,問題仍然存在 - 如何確切地找出問題所在,而不訴諸暴力手段?

回答

1

這裏是強制性答案 - 沒有更好的方法,沒有更深入地理解依賴樹,這往往只能通過評論和看現在的工作來完成。這是我使用clojure和使用gen-class進行Java類加載的經驗。

希雷斯希望這不是最高的投票答案。