简体   繁体   English

RMI UnmarshalException

[英]RMI UnmarshalException

As I am coding RMI system, I ran into problem with exception at client side 我在编码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)

as com.cs.entity.LectureCourse is a class that should be downloaded by client at runtime using RMI codebase feature I have checked to make sure 作为com.cs.entity.LectureCourse是一个类,应由客户端在运行时使用RMI代码库功能下载,我已检查该类以确保

  1. the codebase at server VM argument is set correctly and 服务器VM参数上的代码库设置正确,并且
  2. the client VM option -Djava.security.policy= is also correctly set. 客户端VM选项-Djava.security.policy =也已正确设置。
  3. -Djava.rmi.server.hostname is also used to make sure registry get things correctly -Djava.rmi.server.hostname也用于确保注册表正确获取内容

When I ran client and server at same node it works but exception is displayed at client when separate physical machine holds server and client separately. 当我在同一节点上运行客户端和服务器时,它可以工作,但是当单独的物理机分别持有服务器和客户端时,客户端会显示异常。

Does anyone saw this problem before? 有人看过这个问题吗? Please help... 请帮忙...

@EJP @EJP

Following is the code I used to start RMI registry (inside tomcat 7 contextInitialized) 以下是我用来启动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)

and this is the code I used to lookup registry in Client 这是我用来在客户端中查找注册表的代码

    System.setSecurityManager(new RMISecurityManager());

    final String HOST = "192.168.1.11";
    final int port = 8899;
    final Registry registry = LocateRegistry.getRegistry(HOST, port);

I think they work correctly but the error frustrates me a lot 我认为它们可以正常工作,但是错误让我很沮丧

I think I find where the problem is. 我想我找到了问题所在。 as mentioned before, RMI registry was started at Tomcat 7 contextInitialized method which should be invoked at starting up of the web project. 如前所述,RMI注册表是从Tomcat 7 contextInitialized方法启动的,应在启动Web项目时调用该方法。 it turns out the same piece of code for RMI server works pretty well if it is in an independent main Application. 事实证明,如果RMI服务器位于独立的主应用程序中,则同一段代码可以很好地工作。 according to my several tests in different RMI server configurations, I concluded that 根据我在不同RMI服务器配置中的几次测试,我得出的结论是

  1. Tomcat 7 contextInitialized method does something different then ordinary java main program Tomcat 7 contextInitialized方法的作用与普通的Java主程序不同
  2. I am not sure but codebase seems work only if the URL(I am using webserver) indicates to a specific jar file rather then directory. 我不确定,但是只有在URL(我正在使用网络服务器)指示特定的jar文件而不是目录的情况下,代码库才能正常工作。 (this could be my misunderstanding of the tutorial or something like that) (这可能是我对本教程或类似内容的误解)

So the question turns out to be why Tomcat 7 does not start RMI registry differently? 因此,问题出在这就是为什么Tomcat 7不会以不同的方式启动RMI注册表? I am still working on that 我还在努力

Tomcat 7 contextInitialized method does something different then ordinary java main program Tomcat 7 contextInitialized方法的作用与普通的Java主程序不同

Of course it does. 当然可以。 But without knowing what specific expectations you have, it is impossible to comment further. 但是,如果不知道您有什么具体期望,就无法进一步评论。

I am not sure but codebase seems work only if the URL(I am using webserver) indicates to a specific jar file rather then directory. 我不确定,但是只有在URL(我正在使用网络服务器)指示特定的jar文件而不是目录的情况下,代码库才能正常工作。 (this could be my misunderstanding of the tutorial or something like that) (这可能是我对本教程或类似内容的误解)

It works a lot better because there is only one download, and you don't have to sprinkle .class files all over your codebase server: just deploy one or more JAR files. 它的效果要好得多,因为只有一个下载,而且您不必在整个代码库服务器上散布.class文件:只需部署一个或多个JAR文件。

If you're expecting RMI to load a JAR file from a directory without being specifically told to do so, it won't. 如果您期望RMI从目录中加载JAR文件,而无需特别告知,则不会这样做。 If you don't name a JAR file it will look for .class files. 如果您不命名JAR文件,它将查找.class文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM