2010-11-16 124 views
2

我正在尋找一種在運行時將類重新加載到Java中的方法。動機是使調試更高效。該應用程序是一種典型的客戶端/服務器設計,可同步處理請求。爲每個請求實例化一個「處理程序」對象。這是我打算動態替換的唯一課程。由於每個請求處理一個新的實例,重新加載這個類不會有任何副作用。簡而言之,每當此模塊發生更改時,我都不想重新啓動整個應用程序。Java,運行時類重新加載

在我的設計中,Java進程意識到一個.class文件已在請求之間的類路徑中更新。發生這種情況時,「處理程序」類將被卸載並加載一個新的類。

我知道我可以使用classLoader接口來加載一個新類。我似乎無法找到正確的「卸載」方式。

+1

您是否嘗試過在調試器中使用熱啓動設施? – 2010-11-16 13:40:42

回答

3

如果沒有剩餘的引用,類將像其他任何對象一樣被卸載和垃圾收集。這意味着不能有可達的類實例(由特定的類加載器實例加載),並且類加載器實例本身也必須符合垃圾回收的條件。

所以基本上,你所要做的就是創建一個新的類加載器實例來加載新版本的類,並確保沒有引用舊版本的實例。

1

我相信你實際上需要有一個類加載器的層次結構,爲了重新加載,你實際上擺脫了低級別的類加載器(通過normall GC的方式),因此它加載了所有的類。據我所知,Java EE應用服務器使用這種技術來重新加載應用程序,並且當在一個類加載器中加載的框架代碼想要使用在其他地方加載的類時,有各種有趣的結果。

0

截至2015年,Java的類重新加載是一個缺失的功能。

  • 使用OSGi來創建類重新加載應用程序。
  • 使用jrebel進行測試。還有一些其他人做同樣的事情。
  • 使用應用程序服務器並將要重新加載的零件外部化到單獨的Web應用程序中。然後繼續部署/取消部署。由於懸掛舊的ClassLoader實例,您最終會得到一些perm gen space溢出錯誤。
  • 使用腳本運行器來執行部分可更改代碼。 JSR-223 Java腳本API支持腳本語言「Java」。

我寫了一個關於類重新加載的系列。但所有這些方法都不利於生產。

恕我直言,這個類重載是凌亂的Java和它的不值得嘗試的。但我非常希望這是java中的規範。