Java 客户端从何处获取尚未添加到注册表的远程类的定义?

Java 客户端从何处获取尚未添加到注册表的远程类的定义?,java,rmi,Java,Rmi,我成功地创建了一个RMI应用程序,它完成了我需要它完成的任务,但我在理解客户端获取远程对象定义的位置时遇到了一些困难。例如: 我有一个向rmiregistry注册自身的服务器(允许客户机在其上调用方法) UnicastRemoteObject.exportObject(新服务器(),0) 运行reg.list()确认我的服务器确实已添加到注册表中。我有另一个远程对象(rObj)在与服务器相同的JVM上运行。这不会添加到注册表中 在我的客户端中,我可以通过在注册表中查找Server来获得服务器类的

我成功地创建了一个RMI应用程序,它完成了我需要它完成的任务,但我在理解客户端获取远程对象定义的位置时遇到了一些困难。例如:

我有一个向rmiregistry注册自身的服务器(允许客户机在其上调用方法)

UnicastRemoteObject.exportObject(新服务器(),0)

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

在我的客户端中,我可以通过在注册表中查找
Server
来获得服务器类的定义:

reg.lookup(“服务器”)

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

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


如果是这样,客户机如何知道在服务器上查找远程类。服务器是否几乎被视为客户端类路径的扩展(它将求助于检查服务器中不在其自身类路径中的类)?

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

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


更新:我在这里吃我的话,当然能够编译文件,并在运行时在类路径上提供类,或者两个不同的问题。由于您根本没有提到类路径,我假设您无论如何都会在客户端拥有这些类。

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

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

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

这里详细解释了这一点:

rObj是否在服务器实例中使用?它是从服务器的任何方法返回的吗?它是服务器方法的一个参数,但不是由任何服务器方法返回的。这里可能我错了,但是,如果rObj是远程方法的一个参数,那么本地客户端应该有一个要传递的rObj的类定义。因此,通过RMI公开服务器对象还公开了您可能需要作为参数的rObj类。我认为,如果您添加了服务器和客户端的代码片段,就会更容易理解这个问题。这意味着我可以在客户端上创建
rObj
的新实例。客户端和服务器需要一起编译吗?@richzilla:你是怎么做到的?使用“new”或任何其他API?使用new。所以我只需要
new rObj()
那么
rObj
实际上是名字的类型吗?这非常令人困惑,因为按照命名约定,类名应该是大写的,并且您还将
rObj
称为“另一个远程对象”。但是在任何情况下,我的观点是,您在compiletime已经需要类型
rObj
,因此绝对没有RMI参与创建实例。