尝试使用 Naming.lookup() 创建 RMI 对象时出现以下异常:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: project.server.data.RmiMainObjImpl_Stub
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Naming.java:101)
... 2 more
Caused by: java.lang.ClassNotFoundException: project.server.data.RmiMainObjImpl_Stub
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:425)
at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1206)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1219)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:452)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:185)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:214)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
... 4 more
奇怪的是,这个错误只发生在 Linux 和 AIX 下,而不会发生在 Windows 下。该错误一直发生,但似乎在 某些 Java 版本下有效:
- 原始 jar 是在 Windows 机器上使用 1.6.0u30 构建的
- 原始 jar 在使用 1.7.0u60 的 Linux 下不能工作,但可以在 1.6.0u24 下工作
- 原始 jar 无法在使用 1.6 64 位的 AIX 下运行,但可以在 32 位上运行
- 在使用 1.7.0u60 的 Linux 机器上构建 jar 实际上不会在该机器上使用相同的运行时
我的策略文件似乎已正确设置并被识别(不过,我猜如果不是这样我会遇到不同的错误):
grant {
permission java.security.AllPermission "", "";
};
我正在使用与此类似的命令行执行 java:
java -cp ./.:./JProjApi.jar:./MyRMI.jar -Djava.security.policy=./policy.all com/project/rmi/Main
代码如下所示:
System.setSecurityManager(new RMISecurityManager());
rmiObj = (project.server.data.RmiMainObj_1_0) Naming.lookup("rmi://172.17.44.45/RMIMain");
我无权访问服务器端(而且我正在使用具有必要的客户端接口(interface)的 jar)。
对可能出现的问题有什么想法吗?
最佳答案
the stub class [is] not in the client-side jar.
stub 类必须在客户端 JAR 文件中,除非您使用代码库功能。
why does the Windows version work?
如果它在一个平台上工作而不在其他平台上工作,则 stub 类显然在它工作的平台上的 CLASSPATH 中,而不在它不工作的平台上。或者,如果您使用的是代码库功能(您没有提及任何内容),则无法从所有平台访问代码库 URL。
关于 stub 上的 Java RMI ClassNotFoundException 发生在 Linux 而不是 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24154240/