我有一个简单的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