我正在运行一个RMI应用程序,没有安全管理器:RMI类加载器禁用的异常来了(I am running a RMI application and no security manager: RMI class loader disabled exception comes)

740 IT屋

This is the whole exception:

Computeappengine exceptionRemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: Client.prog (no security manager: RMI class loader disabled)
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: Client.prog (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:334)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at Engine.ComputeappEngine_Stub.executeTask(Unknown Source)
at Client.computeappprog.main(computeappprog.java:23)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: Client.prog (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: Client.prog (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:373)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:163)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:288)
... 9 more

My client package contains two classes Computeappproj which contains main also and prog

I already searched 1000 of forums. Nothing helped.

Hoping for something positive

and good

may be...

解决方案

The problem actualy lies in a classloading. When you're transferring some non-jdk objects (i.e. objects of your own classes) via RMI you need to ensure, that both JVMs, client and server, has your custom class in a classpath. In your case server lacks Client.prog class, so it's unable to reconstruct an object from binary representation - Client.prog class bytecode is necessary for that. There are generally two ways to resolve this issue:

  1. Easy one: copy all your data transfer object classes to both client's and servers's classpath. So none of them will be confused with unknown classes. For a somewhat serious you might even want to create a separate JAR with DTO classes for the ease of maintenance.

  2. Challenging one: enable remote classloading. In short, this technique enables your server to download class bytecode from a client and vice versa, if necessary. This option has a clear security issue (dowloading potentialy unsafe code), so it's disabled by default. To enable it you should use -Djava.rmi.server.codebase property with URL defined and set an appropriate classloader (RMIClassloader or it's descendant) to make Java security system happy. Here's the useful link with some background theory and troubleshooting guide: link

这是整个例外:



  Computeappengine exceptionRemoteException发生在服务器线程中;嵌套异常是:
java.rmi.UnmarshalException:error unmarshalling arguments;嵌套异常是:
java.lang.ClassNotFoundException:Client.prog(没有安全管理器:禁用RMI类加载器)
java.rmi.ServerException:在服务器线程中发生RemoteException;嵌套异常是:
java.rmi.UnmarshalException:error unmarshalling arguments;嵌套异常是:
java.lang.ClassNotFoundException:Client.prog(没有安全管理器:禁用RMI类加载器)
在sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:334)
at sun.rmi.transport.Transport $ 1.run(Transport.java:159)
在java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall (Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run0(TCPTransport .java:790)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(TCPTransport.java:649)
在java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java :886)
在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)
在java.lang.Thread.run(Thread.java:662)
在sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transpo rt.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
在Engine.ComputeappEngine_Stub.executeTask(未知来源)
在Client.computeappprog.main(computeappprog.java:23)
导致:java.rmi.UnmarshalException:error unmarshalling arguments;嵌套异常是:
java.lang.ClassNotFoundException:Client.prog(没有安全管理器:禁用RMI类加载器)
在sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport $ 1.run(Transport.java:159)
在java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall (Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run0(TCPTransport .java:790)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(TCPTransport.java:649)
在java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java :886)
在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)
在java.lang.Thread.run(Thread.java:662)
导致通过:java.lang.ClassNotFoundException:Client.prog(不安全管理器:禁用RMI类加载器)
at su n.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:373)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:163)
在java.rmi.server.RMIClassLoader $ 2 .loadClass(RMIClassLoader.java:620)
在java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197 )
在java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
在java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
在java.io.ObjectInputStream。 readOrdinaryObject(ObjectInputStream.java:1731)
在java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
在java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
在sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
在sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:288)
... 9更多


我的客户端包包含两个类 Comput eappproj 其中包含 main 还和
prog



我已经搜索了1000个论坛。没有任何帮助。



希望获得积极的东西



和好



可能是...


解决方案

问题实际在于一个类加载。当您通过RMI传输一些非jdk对象(即您自己的类的对象)时,您需要确保JVM,客户端和服务器都有一个类路径中的自定义类。在您的情况下,服务器缺少Client.prog类,因此无法从二进制表示形式重建对象 - Client.prog类字节码是必需的。
通常有两种方法可以解决这个问题:




  1. 容易的一个:将所有数据传输对象类复制到客户端和服务器的类路径。所以他们都不会与未知的课程混淆。对于一个有点严重的你甚至可能想创建一个单独的JAR与DTO类,以便于维护。


  2. 挑战一:启用远程类加载。简而言之,这种技术使您的服务器能够从客户端下载类字节码,反之亦然,如有必要。此选项有明确的安全问题(下载潜在的不安全代码),因此默认情况下禁用。要启用它,您应该使用定义URL的-Djava.rmi.server.codebase属性,并设置一个适当的类加载器(RMIClassloader或它的后代),使Java安全系统开心。以下是一些背景理论和故障排除指南的有用链接:链接



本文地址:IT屋 » 我正在运行一个RMI应用程序,没有安全管理器:RMI类加载器禁用的异常来了