RMI问题 – 客户端在哪里获取尚未添加到注册表的远程类的定义?

我设法创建了一个RMI应用程序,它完成了我需要它做得非常成功的事情,但是我很难解决客户端获取远程对象定义的问题。 例如:

我有一个服务器,它使用rmiregistry注册自己(允许客户端调用方法)。

UnicastRemoteObject.exportObject(new Server(), 0);

运行reg.list()确认我的服务器确实已添加到注册表中。 我有另一个远程对象(rObj)在与服务器相同的JVM上运行。 这不会添加到注册表中。

在我的客户端中,我可以通过在rmiregistry中查找Server来获取我的Server类的定义:

reg.lookup("Server")

之后可以自由创建rObj的实例。 我的问题的关键是,我的客户端在哪里获得rObj的定义,即使它从未被添加到注册表中。

我知道它必须来自服务器,因为存储类和接口的地方。 与Server的连接是否会自动打开管道以接收其他远程类?

如果是这样,客户端如何知道在服务器上查找远程类。 是否将服务器视为客户端类路径的扩展(它将使用检查服务器中不在其自己的类路径中的类)?

首先,要意识到没有必要从服务器设置动态类加载以使用RMI。 如果您将接口和实现编译到客户端和服务器jar中,那么一切都会正常工作。 这就是我几乎总是实现RMI的方式。

如果你有充分的理由从服务器动态加载类,你需要在某个地方设置一个具有接口和实现类的HTTP服务器(最好是在一个jar文件中,尽管类目录也可以工作)。 这不会作为RMI的一部分自动发生,您需要构建jar并将它们放在Web服务器上的某个位置。 然后使用指示此jar文件的URL的系统属性启动客户端:

 -Djava.rmi.server.codebase=http://webline/public/mystuff.jar 

这里有详细解释: http : //download.oracle.com/javase/1.5.0/docs/guide/rmi/codebase.html

如果使用new来创建与rObj相同类型(例如, T )的新实例,那么Java编译器当然知道T的定义,并且您的应用程序也在运行时知道它。 在这种情况下,根本不涉及RMI。

但也许我误解了你的问题? 你究竟如何“自由创建rObj实例”?

更新:我在这里吃我的话,当然能够编译文件,并在运行时在类路径上提供类或两个不同的问题。 因为你根本没有提到类路径,所以我假设你不知何故最终在客户端上有了这些类。