RMI UnmarshalException

时间:2013-01-16 06:50:21

标签: java rmi

当我编写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代码库功能下载的类我已经检查以确保

  1. 服务器VM参数的代码库设置正确且
  2. 客户端VM选项-Djava.security.policy =也已正确设置。
  3. -Djava.rmi.server.hostname也用于确保注册表正确无误
  4. 当我在同一个节点上运行客户端和服务器时,它可以工作,但是当单独的物理机器分别保存服务器和客户端时,会在客户端显示异常。

    之前有人看过这个问题吗?请帮忙......

    @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)
    

    这是我用来在Client

    中查找注册表的代码
        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服务器配置中的几个测试,我得出结论

    1. Tomcat 7 contextInitialized方法与普通的java主程序不同。
    2. 我不确定,但是只有当URL(我使用的是webserver)指向特定的jar文件而不是目录时,代码库似乎才有效。 (这可能是我对教程的误解或类似的东西)
    3. 所以问题结果是Tomcat 7不能以不同的方式启动RMI注册表的原因?我还在努力

1 个答案:

答案 0 :(得分:0)

  

Tomcat 7 contextInitialized方法做了与普通java主程序不同的东西

当然可以。但是,如果不知道你有什么具体的期望,就不可能进一步评论。

  

我不确定,但是只有当URL(我使用的是webserver)指向特定的jar文件而不是目录时,代码库似乎才有效。 (这可能是我对教程的误解或类似的东西)

它的效果要好得多,因为只有一次下载,而且您不必在代码库服务器上遍布.class文件:只需部署一个或多个JAR文件。

如果您期望RMI从目录加载JAR文件而没有明确告知这样做,则不会。如果您没有命名JAR文件,它将查找.class文件。