繁体   English   中英

服务器中的RMI UnmarshalException

[英]RMI UnmarshalException in server

我试图在Eclipse(在Windows 7 x64上)上的http://www.ejbtutorial.com/java-rmi/a-step-by-step-implementation-tutorial-for-java-rmi中复制该教程。

我只是复制了代码,因此,假设一切正确完成,它应该可以工作。

我必须更改path变量,因为rmicstart rmiregistry在每个文件夹中均不起作用。 现在我的路径变量是这样的:

C:\Program Files\Java\jdk1.7.0_25\bin;C:\OCaml\bin;C:\Program Files (x86)\EasyPH
P-DevServer-13.1VC11\binaries\php\php_runningversion;C:\Program Files (x86)\NVID
IA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\W
bem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Nmap

我在开始时添加了“ C:\\ Program Files \\ Java \\ jdk1.7.0_25 \\ bin”。 现在,当我打开cmd并数字启动rmiregistry时,它可以正常工作。

问题是,当我尝试在Eclipse上运行服务器时,在cmd上启动了rmiregistry之后,它不起作用并显示:

Addition Server failed: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: AdditionInterface

我在教程中设置了代码库,所以我真的不明白发生了什么...真的很感谢任何建议。 提前致谢。

这是堆栈跟踪:

    java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: AdditionInterface
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at java.rmi.Naming.rebind(Naming.java:177)
    at AdditionServer.main(AdditionServer.java:10)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: AdditionInterface
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
    Caused by: java.lang.ClassNotFoundException: AdditionInterface
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1208)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:270)
    at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1221)
    at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:731)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:675)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:612)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:263)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1556)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1512)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    ... 13 more

编辑:请注意,即使执行Addition类的Rmic,创建存根,即使在Addition_Stub而不是AdditionInterface上,也始终存在unmarshallException

RMI很难使用。 太多的安全问题,太多的开放端口以及太容易损坏。

但是,根据我的建议,我建议您将接口移动并由RMI类转换到一个小jar文件中,将其传递给rmiregistry并且不要设置代码库属性。

启动rmiregistry的命令,您应该在此处设置jar的完整路径:

rmiregistry -J-classpath -J/home/user/dev/project/project-iface.jar

启动服务器时,请将其绑定到已存在的rmiregistry ,而不要启动它自己的服务器。 对于客户端,请使用与接口类完全相同的jar, rmiregistry在启动rmiregistry时使用。

这样可以避免远程类加载的问题,但是如果您的接口类经常更改,则可以增加开发过程的复杂性。

与您的示例相关,您应该执行以下步骤:

  1. 在Eclipse中创建另一个项目,将文件AdditionInterface.java移到该项目中。 项目应在jar中编译。 将其命名为iface.jar或类似名称。
  2. 从客户端和服务器端项目中删除AdditionInterface。
  3. 将iface.jar添加为客户端和服务器的依赖项。
  4. 从客户端和服务器上删除不必要的文件security.policy。
  5. 删除VM参数以运行客户端和服务器。
  6. 删除行System.setSecurityManager(new RMISecurityManager()); 来自客户端和服务器代码。
  7. 构建工件iface.jar
  8. 在cmd中运行命令:rmiregistry -J-classpath -J / home / grigory / dev / test24804087 / out / artifacts / iface_jar / iface.jar
  9. 启动服务器,您将收到消息“附加服务器已准备就绪”。
  10. 运行客户端。 您将收到消息“结果为:19”

项目结构示例(适用于IDEA) 在此处输入图片说明

RMI Class Loading不应该通过RMI接口加载,而是从外部资源(例如Web中的URL)加载(这是代码库所指向的)。

因此,如果在服务器端有一些类,则必须在客户端应用程序的类路径上具有相同的类,或者作为Web资源公开可用,反之亦然。

暂无
暂无

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

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