我有一個簡單的RMI'compute'服務器應用程序(類似於this),它通過RMI從客戶端接受某些接口類型的對象,執行接收對象的compute()
方法,並通過RMI返回結果遠程客戶端。這些工作是「一次性」的,不同工作之間或不同工作對象之間沒有互動。卸載通過RMI傳遞的類
我希望能夠修改類並將實例提交給計算服務器以供執行,而無需不斷重新啓動服務器JVM。然而,當一個已被修改的類再次作爲參數提交給遠程調用時,它的方法行爲不會改變(這也發生在匿名類中)。我一直在閱讀關於序列化的知識,並且我意識到這是因爲ClassLoader無法修改現有類。
從我對SO和其他地方的閱讀中我發現,不知怎麼的,加載流類的ClassLoader必須GC'd並替換爲加載我的類的新版本。我有一個想法如何做到這一點,但底層RMI運行時情況似乎很複雜,並且它有自己的RMIClassloader。
我的問題是:加載通過RMI參數收到的每個新版本的類最簡單的方法是什麼?理想情況下,我正在尋找一種方法讓每個遠程調用都能得到一個新的ClassLoader,並在返回時處理它。沒有關於定製ClassLoaders和RMI內部的複雜知識,這是否可行?
歡迎閱讀材料或例子的任何指針!
編輯:這裏是計算服務器的遠程接口:
public interface ComputationEngine extends Remote {
public Object execute(Task t) throws RemoteException;
}
和「計算工作」界面,Task
:
public interface Task extends java.io.Serializable {
public Object compute();
}
它不是類加載器必須GCed(雖然你最終會耗盡內存,如果它不是)。 IIRC,在部分RMI實現中,有一個從代碼庫到'ClassLoader'的映射。 – 2010-08-29 15:10:24
什麼是compute()的參數?客戶端是否發送他們想要執行的類文件,或者您是否正在嘗試動態更新compute()接口的實現,因爲出現錯誤而無需重新啓動服務器? – 2010-08-29 16:42:39
@ Tom:我的印象是,卸載類的唯一方法是GC調用'ClassLoader'。從我的實驗看來,所有遠程調用都使用相同的「ClassLoader」。不過謝謝,我會使用這些術語進行更多搜索。 – willjcroz 2010-08-29 20:19:16