2012-02-15 46 views
2

我有一個應用程序需要能夠更新自己的部分(一次一個類),而無需停止和重新啓動。使用JavaCompiler API,直接生成修改的類源代碼,重新編譯,加載和實例化類。我可以在內存中執行此操作(不從磁盤或網絡讀取文件)。動態程序更新,運行時編譯和類加載器

應用程序永遠不會實例化此類的多個對象。這個對象只有兩個或三個引用。當修改後的類被加載並實例化時,所有這些引用將被更改爲新對象。我也可以保證在加載修改後的類時,受影響的類中沒有方法正在另一個線程中運行。

我的問題是這樣的:我的類加載器在加載與之前加載的類具有相同名稱的修改後類時是否有問題?

如果我沒有在類加載器中顯式實現加載類的緩存,是否會避免問題?或者可以委派給父類裝載器仍然會導致問題?

我希望使用我的類加載器的單個實例,但如果有必要,我可以在每次更新一個類時實例化一個新實例。

注:我看着OSGI,它似乎比我需要的多一點。

+0

我有一些非常相似的東西。您必須指定使用JDK才能編譯它,否則您將在JavaCompiler返回null時收到錯誤。 – 2012-02-15 17:42:38

回答

0

好吧,它應該工作:當你加載新類時,它將替換相應表中的類名,並且內存應該是GC'd。也就是說,我會用一個真正的短程序來進行艱苦的測試,這個程序編譯一個非平凡的類,並替換它,比如說10,000次。

1

有在http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html

在這個有用的例子,我們相當多的動態類的重載自己(使用Groovy的編譯)。請注意,如果你有類依賴關係,那麼你可能需要在重新加載時重新編譯這些依賴關係。在開發堆棧中,我們會跟蹤這些依賴關係,然後在依賴關係過時時重新編譯。在生產堆棧中,我們選擇了非重載ClassLoader,並在任何更改時創建新的ClassLoader。所以你可以這樣做。

順便說一句 - 你可能會發現GroovyScriptEngine在http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.5/groovy/util/GroovyScriptEngine.java#GroovyScriptEngine非常有趣,如果你想挖掘他們如何做到這一點。