如何设置rmiregistry使用的类路径?

我正在尝试制作Java RMI客户端/服务器应用程序。 我在启动应用程序的服务器端时遇到问题,因为当我尝试启动应用程序的服务器端时,它在调用Registry.bind()方法期间一直运行到ClassNotFoundException

我从这里的简单教程开始: http : //docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html 。 按照这些说明操作后,它最初抛出一个ClassNotFoundException,抱怨它找不到“example.hello.Hello”。 我能够通过从教程中的destDir目录启动rmiregistry来解决这个问题,因为rmiregistry显然使用它的初始起始目录作为其类路径的一部分。

之后我开始使用我的其他测试应用程序,直到我开始在服务器类中使用第三方jar文件之前我一直很好。 现在,如果我的服务器类引用任何jar文件中的任何内容,则Registry.bind()会抛出ClassNotFoundException,因为rmiregistry应用程序不知道这些jar文件。

据我所知,rmiregistry不接受任何类型的路径启动arg,所以我想知道如何告诉它我想要它承认什么类路径。 根据这里的教程: http : //docs.oracle.com/javase/tutorial/rmi/running.html ,“你必须确保你将运行rmiregistry的shell或窗口没有设置CLASSPATH环境变量或有一个CLASSPATH环境变量,它不包含你想要下载到远程对象客户端的任何类的路径。“ 这听起来与我需要的相反……或者我读错了吗? 有没有人有任何成功启动使用第三方jar的RMI客户端/服务器(在我的情况下,commons-io,commons-logging和rmiio)?

这是在Windows上,顺便说一下。

更新我找到了解决方法。 请参阅下面的答案。

关于取消设置CLASSPATH的注释仅适用于您使用RMI代码库function的情况,因为关于下载类的神秘话语意图暗示。

如果您没有使用代码库function,只需:

  1. 在启动rmiregistry,之前rmiregistry,根据需要设置CLASSPATH环境变量rmiregistry,如此处其他地方所示,或
  2. -J-Djava.class.path=...启动rmiregistry
  3. 使用LocateRegistry.createRegistry().在服务器JVM中启动注册表LocateRegistry.createRegistry(). 这在很多方面都是最好的解决方案,因为它与JVM一起生存和死亡,共享其类路径,并且顺便提一下也符合代码库function的要求。

如果你这样做(3),你必须将返回值存储到静态变量中以防止它被垃圾收集,这会导致注册表被取消导出,这可能导致远程对象的DGC,这可能导致它GC’d,这将导致监听线程退出,这可能导致整个JVM退出。

没有RMI注册表特定的java类路径。 它应该使用与Java系统其余部分相同的类路径。 您可以通过在命令行或OS环境中指定类路径来设置类路径。 虽然有点过时,但这篇文章应该指出你正确的方向。

(我最初发布这个答案作为我的问题的更新.Per Zecas在其中一条评论中提出的建议,我将其移至答案部分。)

我能够通过不遵守上面问题中引用的第二个教程中的建议来启动服务器部分:

“您必须确保运行rmiregistry的shell或窗口没有设置CLASSPATH环境变量,或者具有CLASSPATH环境变量,该变量不包含要下载到远程对象客户端的任何类的路径。”

我创建了一个CLASSPATH环境变量,并将我的.class输出目录和每个第三方jar文件添加到其中。 我以为我之前尝试过,但我想不是……只是想我会离开我的解决方案以防其他人遇到同样的问题。

如何为rmiregistry设置类路径的示例

Win32的:

 set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar 

UNIX:

 setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar