当我编写 RMI 系统时,我在客户端遇到了异常问题
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: com.cs.entity.LectureCourse
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy1.getNamedClass(Unknown Source)
at com.cs.test.ClientCRUD.main(ClientCRUD.java:40)
作为com.cs.entity.LectureCourse
一个应该由客户端在运行时使用 RMI 代码库功能下载的类,我已经检查以确保
- 服务器 VM 参数的代码库设置正确,并且
- 客户端 VM 选项 -Djava.security.policy= 也已正确设置。
- -Djava.rmi.server.hostname 也用于确保注册表正确获取内容
当我在同一个节点上运行客户端和服务器时,它可以工作,但是当单独的物理机器分别持有服务器和客户端时,客户端会显示异常。
有人以前见过这个问题吗?请帮忙...
@EJP
以下是我用来启动 RMI 注册表的代码(在 tomcat 7 contextInitialized 内)
final String value = "http://192.168.1.11:8080/csl/";
System.out.println(value);
System.setProperty("java.rmi.server.codebase", value);
registry = LocateRegistry.createRegistry(8899)
这是我用来在客户端查找注册表的代码
System.setSecurityManager(new RMISecurityManager());
final String HOST = "192.168.1.11";
final int port = 8899;
final Registry registry = LocateRegistry.getRegistry(HOST, port);
我认为它们工作正常,但错误让我很沮丧
我想我找到了问题所在。如前所述,RMI 注册表是在 Tomcat 7 contextInitialized 方法中启动的,该方法应在启动 Web 项目时调用。事实证明,如果 RMI 服务器在独立的主应用程序中,相同的代码可以很好地工作。根据我在不同 RMI 服务器配置中的几次测试,我得出的结论是
- Tomcat 7 contextInitialized 方法的作用与普通的 java 主程序不同
- 我不确定,但代码库似乎只有在 URL(我正在使用网络服务器)指示特定 jar 文件而不是目录时才有效。(这可能是我对教程的误解或类似的东西)
所以问题变成了为什么 Tomcat 7 没有以不同的方式启动 RMI 注册表?我仍在努力