卸载通过RMI传递的类

时间:2010-08-29 13:35:18

标签: java rmi classloader

我有一个简单的RMI“计算”服务器应用程序(类似于this),它通过RMI从客户端接受某些接口类型的对象,执行接收对象的compute()方法并返回结果通过RMI到远程客户端。这些工作是“一次性”,不同工作之间或不同工作对象之间没有相互作用。

我希望能够修改类并将实例提交到计算服务器以便执行,而无需不断重新启动服务器JVM。但是,当一个已修改的类再次作为参数提交给远程调用时,它的方法行为不会改变(这也会发生在匿名类中)。我一直在阅读有关序列化的内容,我意识到这与ClassLoader无法修改现有类有关。

从我在SO和其他地方的阅读中我意识到,加载流类的ClassLoader必须以某种方式进行GC并替换才能加载我的类的新版本。我知道如何做到这一点,但基础RMI运行时并且它有自己的RMIClassloader,情况似乎很复杂。

我的问题是:加载通过RMI参数接收的每个新版本类的最简单方法是什么。理想情况下,我正在寻找一种方法让每个远程调用获得一个新的ClassLoader并在返回时处理它。如果没有对定制的ClassLoader和RMI内部的复杂知识,这是否可行?

欢迎任何阅读材料或示例的指示!

编辑:这是计算服务器的远程接口:

public interface ComputationEngine extends Remote {
    public Object execute(Task t) throws RemoteException;
}

和'计算工作'界面,Task

public interface Task extends java.io.Serializable {
    public Object compute();
}

2 个答案:

答案 0 :(得分:1)

唯一的方法是在想要更改类时使用新的ClassLoader。 如何使用URLClassLoader并从URL中提供代码

我在我的一个项目中使用它来在jar文件更改时更新API。看看这里: http://code.google.com/p/open-forum/source/browse/trunk/Wiki/org/one/stone/soup/wiki/jar/manager/JarManager.java 第184行

查看您的电子邮件: - )

答案 1 :(得分:0)

这并没有真正回答你的问题,但是有可能将类的一部分更改为数据而不是实际的类。使用Map而不是字段等。你可以减少很少的类,你的代码也可能更简单。