java 我正在运行一个 RMI 应用程序,但没有安全管理器:RMI 类加载器禁用异常来了
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17351336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
I am running a RMI application and no security manager: RMI class loader disabled exception comes
提问by pcc
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.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.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.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
我的客户端包包含两个类Computeappproj
,其中main
还包含和
prog
I already searched 1000 of forums. Nothing helped.
我已经搜索了 1000 个论坛。没有任何帮助。
Hoping for something positive
希望有积极的东西
and good
好的
may be...
也许...
回答by Jk1
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:
问题实际上在于类加载。当您通过 RMI 传输一些非 jdk 对象(即您自己的类的对象)时,您需要确保 JVM、客户端和服务器在类路径中都有您的自定义类。在您的情况下,服务器缺少 Client.prog 类,因此无法从二进制表示中重建对象 - 为此需要 Client.prog 类字节码。一般有两种方法可以解决这个问题:
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.
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
简单一:将所有数据传输对象类复制到客户端和服务器的类路径。所以他们都不会与未知的类混淆。对于有些严肃的人,您甚至可能想要创建一个带有 DTO 类的单独 JAR 以便于维护。
挑战一:启用远程类加载。简而言之,如果需要,这种技术使您的服务器能够从客户端下载类字节码,反之亦然。这个选项有一个明显的安全问题(下载潜在的不安全代码),所以默认情况下它是禁用的。要启用它,您应该使用定义了 URL 的 -Djava.rmi.server.codebase 属性并设置适当的类加载器(RMIClassloader 或其后代)以使 Java 安全系统满意。这是包含一些背景理论和故障排除指南的有用链接:链接
回答by user207421
I am running a RMI application and no security manager: RMI class loader disabled exception comes
我正在运行一个 RMI 应用程序,但没有安全管理器:RMI 类加载器禁用异常来了
No. Read the stack trace again. The exceptionhere is java.lang.ClassNotFoundException: Client.prog
. The stuff in brackets is merely a (literally parenthetical) commenton one of many possible causes.
不。再次阅读堆栈跟踪。这里的例外是java.lang.ClassNotFoundException: Client.prog
。括号中的内容只是对许多可能原因之一的(字面上的括号)评论。
The problemis that Client.prog
isn't on the CLASSPATH of the server. You can tell that from the line:
该问题是,Client.prog
是不是在服务器的CLASSPATH。你可以从这一行看出:
java.rmi.ServerException: RemoteException occurred in server thread
The solution is to either deploy the class to the server or use the codebase feature.
解决方案是将类部署到服务器或使用代码库功能。