java - 包含多个 JAR 的 RMI

标签 java jar rmi codebase

我正在使用 3 个 JAR 编写 RMI 程序:

  • RMIServer,包含服务器端类
  • RMIClient 包含客户端类
  • RMIResource 包含服务器和客户端共享内容(接口(interface)、自定义异常)

为了制作单独的 JAR 文件,我在 NetBeans 中创建了 3 个项目,然后在其他 2 个项目的“库/构建”部分中声明了共享 Jar。

一切都很好,没有错误。

但是当我尝试通过命令行启动服务器时(在我想到将共享文件放入不同的 JAR 中之前这很简单),这突然变得很痛苦......

以下是我尝试过的一些命令示例:

  • 保持 ClassPath 指向服务器资源,但使用双 CodeBase

    java -cp ~/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

结果:

Network exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: rmiresource.BookingManager
...
  • 使用双 ClassPath 但保持 CodeBase 指向服务器资源

    java -cp "~/NetBeansProjects/RMIServer/dist/RMIServer.jar;~/NetBeansProjects/RMIServer/dist/lib/RMIResource.jar" -Djava.rmi.server.codebase=file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar rmiserver.Shop
    

结果:

Exception in thread "main" java.lang.NoClassDefFoundError: rmiserver/Shop
Caused by: java.lang.ClassNotFoundException: rmiserver.Shop
...
  • 使用双 ClassPath 和双 CodeBase

    java -cp "~/NetBeansProjects/RMIServer/dist/RMIServer.jar;~/NetBeansProjects/RMIServer/dist/lib/RMIResource.jar" -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

结果:

Exception in thread "main" java.lang.NoClassDefFoundError: rmiserver/Shop
Caused by: java.lang.ClassNotFoundException: rmiserver.Shop
...

编辑: 我正在本地计算机上工作,模拟远程连接。因此我使用"file"协议(protocol)而不是“http”。

我错过了什么吗?感谢您提供的任何帮助

<小时/>

我再次测试了我的第一个解决方案,因为它是最有希望的:

    java -cp ~/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop

还是失败了。

然后我在 Windows 上进行了测试:

  1. 使用空类路径设置 rmiregistry(并 cd 到 java/bin 目录)

    set CLASSPATH=""; export CLASSPATH
    start rmiregistry
    
  2. 使用与之前相同的命令启动服务器(Win 环境发生变化)

    java -cp c:/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/c:/netbeansprojects/rmiserver/dist/rmiserver.jar file:/c:/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

而且......它成功了!

我在 Linux 和 Windows 上清理/重建了解决方案,但它仍然无法在 Linux 上运行而在 Windows 上运行...我在两者上使用相同的 Netbeans 版本!

有人可以向我解释一下吗?我在 Linux 上使用 JDK 6,在 Windows 上使用 JDK 7:这会产生影响吗?

最佳答案

文件:代码库无法在本地计算机上运行。您需要使用 HTTP。您可以使用指向共享目录的 file: URL,这样该 URL 在客户端有意义,但这在 LAN 之外不起作用。

除非您使用代码库功能,否则 RMI 注册表需要通过其类路径访问共享类: rmiregistry -J-Dclasspath=... 使用 LocateRegistry.createRegistry() 更简单,然后它位于与以下相同的 JVM 中当然,您的远程对象并使用相同的类路径。

关于java - 包含多个 JAR 的 RMI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7278395/

相关文章:

java - 如何在java程序中导入用户定义的包?

根据 vcard 3.0 格式,用于 75 个字符行的 java base64 编码器

java - 如何使用来自多个模块的依赖项构建 Uber jar

Java RMI : ConnectException: Connection timed out: connect

java - RMI 与 REST 服务

java - 如何编写一个 Consumer 来计算它被调用了多少次?

java - 将用户的备注作为字符串传递给 java bean

java - ExceptionInInitializerError - 使用getResourceAsStream读取jar包中的文件

android - Proguard 和 HashMap<String, MyObject>

java - 运行可执行 jar 文件时未找到类错误(使用 eclipse 导出的 RMI 应用程序)