2010-02-17 114 views
1

我的應用程序由多個JAR文件組成。我想迭代所有的JAR文件,並找到所有繼承特定類的類,以便我可以使它們的靜態初始化器運行。如何枚舉Java中超類的所有子類

我查看了Javadocs的java.lang.ClassLoader,但找不到任何這樣做的方法。

我試圖實現「產品交易者」模式(http://www.ubilab.com/publications/print_versions/pdf/plop-96-producttrader.pdf),並在抽象超類中使用「自注冊」類。超類將有一個HashMap,它映射子類提供的服務和處理該服務的java.lang.Class文件。

問題是一個類直到加載它才運行它的靜態初始化器。如果我可以迭代所有的子類,我可以強制每個加載並運行初始化器。

謝謝,拉爾夫

回答

5

這通常不是可以解決的。 ClassLoader不需要能夠遍歷它可能加載的類。 不能的ClassLoader最簡單的例子是,當您從http://基本URL加載類時:HTTP沒有提供任何標準方式來枚舉任何給定的URL的內容。

更好的實現方法是使用ServiceLoader,讓所有的實現類通過jar文件中的簡單條目註冊自己。

+0

ServiceLoader似乎是相當「重量級」的使用 – Ralph 2010-02-17 14:42:19

+0

@Ralph:真的嗎?它看起來正是你想要的。無需執行任何註冊。只需向ServiceLoader詢問接口的所有實現即可。 – 2010-02-17 14:59:02

+0

我會仔細看看。謝謝。現在,如果我能讓ANT自動構建META-INF的東西,它可能是完美的。 – Ralph 2010-02-17 15:24:49

0

如果你真的需要這樣做,唯一真正的方法是迭代類路徑,掃描類文件的jar和目錄,加載該類並查看它的父類。

請注意,一些類將有靜態初始化代碼,可能有不良副作用,例如,從運行時加載X11類可能會長時間掛起。如果可能,嘗試限制將哪些類加載到特定的軟件包,例如com.company(當然,你可以通過類文件相對於根路徑到類路徑項來標識包)。

[注由約阿希姆·紹爾建議的ServiceLoader,或提供類似的機制是一個更好的解決方案框架]

0

這顯然不是解決的很乾脆。

但是,有解決方案,就像這個Javaworld article中提到的解決方案。

一般來說,它包括探索CLASSPATH中的所有元素。如果它們是jar文件,請探索它們尋找類,加載這些類並查看它們是否擴展了引用基類。 但是,我強烈建議你使用更「成熟」的機制,如IoC或插件架構。

我很明顯想着JSPF作爲一個例子。