Java 如何告诉注册中心在哪里查找类?
Java 如何告诉注册中心在哪里查找类?,java,rmi,rmiregistry,Java,Rmi,Rmiregistry,注册表是 同一主机上的RMI服务器用于将远程对象绑定到名称的引导命名服务 现在,我有了这样一个服务器,它使用rmiregistry来提供JNDI public class ObjectProvider { public static void main(String[] args) { System.setProperty("java.rmi.server.codebase", "file:/absolute/path/to/jar/where/person/class/
注册表
是
同一主机上的RMI服务器用于将远程对象绑定到名称的引导命名服务
现在,我有了这样一个服务器,它使用rmiregistry
来提供JNDI
public class ObjectProvider {
public static void main(String[] args) {
System.setProperty("java.rmi.server.codebase", "file:/absolute/path/to/jar/where/person/class/is/my.jar");
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
Context context = new InitialContext(env);
context.bind("jordan", new Person("Michael Jordan"));
Person p = (Person) context.lookup("jordan");
System.out.println("jordan = " + p.getName());
}
}
和人员类别:
public class Person implements Remote, Serializable {
String name;
public Person(String name) { this.name = name; }
public String getName() { return name; }
}
并且rmiregistry
作为rmiregistry&
启动。然而,当我运行代码时,它抱怨在执行bind
时无法解组参数,因为找不到类Person
我知道
rmiregistry
找不到类文件,但我不明白为什么。这是告诉它在哪里可以找到要绑定的类的正确方法吗?虽然我无法发现您的程序的问题(我复制了它并得到了相同的错误),但我可以建议您在启动注册表之前在相同的过程中设置显式的CLASSPATH环境变量。此类路径必须与RMI服务器进程中的相同。例如:
set CLASSPATH=my_class_directory:my_jar1:my_jar2...
rmiregistry &
根据,我承认这不是一个好的实践,它告诉我们从注册表中删除
CLASSPATH
。但是,由于您是从本地主机获取代码,因此总比不让它工作要好。尽管我无法发现您的程序的问题(我复制了它并得到了相同的错误),但我可以建议您在启动注册表之前在同一过程中设置显式的CLASSPATH环境变量。此类路径必须与RMI服务器进程中的相同。例如:
set CLASSPATH=my_class_directory:my_jar1:my_jar2...
rmiregistry &
根据,我承认这不是一个好的实践,它告诉我们从注册表中删除
CLASSPATH
。但是,由于您是从本地主机获取代码,因此总比不让代码正常工作要好。如果代码库URL正确,这是正确的,但是文件:
代码库URL只有在同一主机上运行时才有效,这使得RMI本身毫无意义。另外,Person
还不是RMI服务器,因为它不是导出的远程对象。你确定你需要RMI吗?好吧,这不是我真正的项目,而是为了熟悉JNDI的一个玩具示例。以及RMI作为支持它的技术。我的想法是让ObjectProvider
作为对象的提供者(驻留在一个VM上)。随后,我想让ObjectConsumer
也(驻留在另一个VM上),它将查找提供的对象。你说得对,Person
不是RMI服务器。我想将其实例作为可以通过JNDI查找的对象提供。理论上,ObjectConsumer
是一个RMI
服务器,因为它通过RMI
提供对象,但通过JNDI
作为接口。使用JNDI的事实并不相关。它只是LocateRegistry
API上的一层。它不会干扰代码库的工作。注意:我之前评论中的拼写错误:“提示此”应改为“客户是”。我会尝试使用一个合适的HTTP代码库URL。另外,您的文件:/
URL不正确:开头应该有三个斜杠,而不是一个。您在注释中提到了ObjectConsumer
远程对象,但它没有出现在代码中。您在何时何地构建它,在什么时候设置与之相关的codebase属性?如果不是通过注册表,客户端如何获得ObjectConsumer
?如果代码库URL是正确的,这是正确的,但是文件:
codebase URL只有在同一主机上运行时才起作用,这使得RMI本身毫无意义。另外,Person
还不是RMI服务器,因为它不是导出的远程对象。你确定你需要RMI吗?好吧,这不是我真正的项目,而是为了熟悉JNDI的一个玩具示例。以及RMI作为支持它的技术。我的想法是让ObjectProvider
作为对象的提供者(驻留在一个VM上)。随后,我想让ObjectConsumer
也(驻留在另一个VM上),它将查找提供的对象。你说得对,Person
不是RMI服务器。我想将其实例作为可以通过JNDI查找的对象提供。理论上,ObjectConsumer
是一个RMI
服务器,因为它通过RMI
提供对象,但通过JNDI
作为接口。使用JNDI的事实并不相关。它只是LocateRegistry
API上的一层。它不会干扰代码库的工作。注意:我之前评论中的拼写错误:“提示此”应改为“客户是”。我会尝试使用一个合适的HTTP代码库URL。另外,您的文件:/
URL不正确:开头应该有三个斜杠,而不是一个。您在注释中提到了ObjectConsumer
远程对象,但它没有出现在代码中。您在何时何地构建它,在什么时候设置与之相关的codebase属性?如果不是通过注册表,客户端如何获得ObjectConsumer
。那么代码库是用来做什么的?什么老问题?Regisrtry与代码库一起工作,就像任何其他RMI系统一样。它只能工作,因为它只是另一个RMI服务器。有很多工作代码可以证明这一点。@EJP你是对的:应该没有问题,但在这种情况下我仍然认为它是一个有效的解决方案(我编辑了我的帖子)。好吧,答案解决了我的问题,因为我可以执行我的玩具示例。但是,我希望正确地执行此操作,即使用java.rmi.server.codebase
选项。指示在启动rmi服务器时应传递VM选项java.rmi.server.codebase
,在我的示例中是ObjectProvider
。不过,问题还是一样的。找不到该类。是的,我已经用