存根上的Java RMI ClassNotFoundException发生在Linux但不是Windows

时间:2014-06-11 03:36:45

标签: java linux rmi classnotfoundexception

尝试使用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无法在Linux下使用1.7.0u60,但可以使用1.6.0u24
  • 使用1.6 64位的原始jar在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");

我无法访问服务器端(我也在使用具有必要客户端接口的jar)。

关于可能出错的任何想法?

2 个答案:

答案 0 :(得分:1)

  

存根类[不]在客户端jar中。

存根类必须位于客户端JAR文件中,除非您使用的是代码库功能。

  

为什么Windows版本有效?

如果它在一个平台而不是其他平台上工作,那么存根类显然位于它工作的平台上的CLASSPATH中,而不是在它没有的平台上。或者,如果您使用的代码库功能尚未提及,则无法从所有平台访问代码库URL。

答案 1 :(得分:0)

确定这一点成为一个低得多的优先事项,但它又回来了。

网络扫描显示没什么异常。

事实证明,它确实至少与Java版本或新Java版本的新设置有关。

此: -Djava.rmi.server.useCodebaseOnly = FALSE 不得不添加到命令行,它现在适用于以前没有工作的那些机器。