2009-08-08 112 views
3

我有一個java代理,它測試字節碼。 我正在使用java 6中的attach apis來允許用戶使用我的java代理動態加載代理和工具以及解除代碼。 我正在使用Boot-Class-Path清單屬性來確保我的javagent類在引導類路徑中,以便我的用戶可以使用ArrayList等工具類。Javaagent類卸載

但是,版本控制會帶來問題。 可以說用戶動態地附加了我的代理的版本1。 然後我給了他第2版。現在,由於他的應用程序服務器從未關閉,因爲他連接了我的代理的版本1,所以版本1的類仍然被加載。

我需要某種方式,當我的客戶端版本2的Javaagent,版本1被卸載。

我知道一個辦法是寫一個客戶類加載器爲我javaagent的課程,並設置類加載器引用設置爲null。 然而,在那種情況下,我不能在引導類路徑中檢測類,因爲我的類加載器將在引導類加載器的層次結構中處於下方,因此我的用戶不能像ArrayList那樣的工具類,因爲如果我在ArrayList的方法中添加一個調用,我的代理程序的類的方法引導類加載程序將無法看到它們。

那麼有什麼辦法來解決引導類路徑問題,並仍然卸載以前的代理類?

+1

您可能想看看JavaRebel(http://www.zeroturnaround.com/javarebel/),它是您試圖執行的商業實現。它可能會告訴你什麼是和不可能的。 – skaffman 2009-08-12 17:06:18

回答

1

我不是這方面的專家,但它似乎像這種卸載替換不直接支持。

但是你需要卸載 - 替換類嗎?

你能代替創建一個永不更改的類,外界會談,在其中內部imlpement一個版本的系統?

例如,創建具有,比如,與ToolAgentImplementation的類名來使用靜態字符串類MyToolAgent。當你第一次發佈時,它被設置爲使用ToolAgentImplementation1_0。當您升級到版本2.0時,您將部署一個名爲ToolAgentImplmenetation2_0的附加類,並更新MyToolAgent類以加載並使用它。你永遠不會卸載1.0版本,但你停止使用它。你在這裏浪費了一些內存,但你實現了版本升級。

我不知道這是不是在您的情況是可行的,但總體看來JVM不支持直接換一個新的版本,但你應該能夠隱藏在某些方面。

0

我不知道這會工作,但它可能給你一些選項...

而不是試圖加載當前代理(我們稱之爲工具劑),增加新的代理(一安裝代理)。安裝程序代理只有1個功能:使用RedefineClasses()來替換原始工具代理類。

如果你的名字有一個版本號的類名(MyToolInstallerV1),可以隨時加載新安裝該更新工具代理的一部分安裝代理。如果大小成爲問題,則安裝程序代理可能會尋找以前的安裝程序,並用一個小的無操作存根替換它們的類。

0

我現在還沒有裝備任何東西,但我只是在玩java.util.ServiceLoader並實現了某種插件架構,並使用URLClassLoader的方法實現了動態JAR加載卸載。

我不知道「儀表」可以用這種方式進行修改,但版本控制和動態加載 - 卸載問題可以被追蹤,並且測試真的很快,因爲硬件是由ServiceLoader完成的只需遵循微小的/ META-INF/services/XXX規範),並且您已準備好:)

此致敬禮。

0

OSGI的完美用例。不知道你是否可以將你的經紀人作爲一個捆綁銷售。