【问题标题】:I am running a RMI application and no security manager: RMI class loader disabled exception comes我正在运行一个 RMI 应用程序并且没有安全管理器:RMI class loader disabled exception come
【发布时间】:2013-06-27 19:10:11
【问题描述】:

这是整个例外:

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

我的客户端包包含两个类Computeappproj,其中还包含mainprog

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

希望有一些积极的东西

很好

可能……

【问题讨论】:

  • 您的服务器没有“Client.prog”的类定义。错误消息似乎很简单。据推测,“Client.prog”类正在客户端和服务器之间发送,因此两个应用程序都需要它在类路径中。

标签: java eclipse-plugin classpath rmi rmiregistry


【解决方案1】:

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

  1. 简单一:将所有数据传输对象类复制到客户端和服务器的类路径。所以它们都不会与未知类混淆。对于有些严肃的人,您甚至可能想要创建一个带有 DTO 类的单独 JAR 以方便维护。

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

【讨论】:

  • 1.绝对是最好的解决方案,除非您真的,真的需要动态类加载(大多数 RMI 应用程序不需要需要)。
【解决方案2】:

我正在运行一个 RMI 应用程序并且没有安全管理器:出现 RMI 类加载器禁用异常

没有。再次读取堆栈跟踪。这里的异常java.lang.ClassNotFoundException: Client.prog。括号中的内容只是对许多可能原因之一的(字面括号)评论

问题Client.prog 不在服务器的 CLASSPATH 上。你可以从这行看出:

java.rmi.ServerException: RemoteException occurred in server thread

解决方案是将类部署到服务器或使用代码库功能。

【讨论】:

  • 不,这不是类路径问题..实际上我没有在 ma 服务器中设置安全管理器,它没有让 ma 服务器动态加载客户端的类,因此必须使用安全管理器.此外, prog 是客户端类,因此不应在服务器端设置其路径。我自己通过一些实验解决了这个问题。感谢您的帮助...
  • @pcc 这确实是一个类路径问题,您可以使用代码库功能解决,而这又需要安全管理器。您以“此外”开头的陈述没有动机且不正确。
猜你喜欢
  • 2012-06-21
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 2023-04-09
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多