我正在研究Java RMI应用程序,并且在将服务器绑定到注册表时遇到问题。我正在使用rmi插件进行eclipse,在我不得不格式化我的电脑之前一切正常。此外,我确信代码是正确的,因为它是作为解决方案给我的那个,所以我的配置一定有问题。 这是代码:
public static void main (String[] args){
try{
RMIChatServer myObject = new RMIChatServerImpl();
System.setSecurityManager(new RMISecurityManager());
Naming.rebind("Hello", myObject);
System.out.println("Remote object bound to registry");
}
catch( Exception e){
System.out.println("Failed to register object " + e);
e.printStackTrace();
System.exit(1);
}
}
它给出的例外情况:
Failed to register object java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: access to class loader denied
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: access to class loader denied
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:177)
at RMIChatServerImpl.main(RMIChatServerImpl.java:175)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: access to class loader denied
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.ClassNotFoundException: access to class loader denied
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:447)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:184)
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:216)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
... 13 more
Caused by: java.security.AccessControlException: access denied ("java.io.FilePermission" "\D:\uni\YEAR 3\Enterprise Programming\java\czat solution 2\bin\-" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
at java.security.AccessController.checkPermission(AccessController.java:555)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at sun.rmi.server.LoaderHandler$Loader.checkPermissions(LoaderHandler.java:1176)
at sun.rmi.server.LoaderHandler$Loader.access$000(LoaderHandler.java:1130)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:411)
... 22 more
我研究了这个问题,大多数人说这是因为代码库设置(我也使用安全策略),我尝试了不同的设置,目前正在使用rmi插件提供的“来自classpath的计算”选项,该选项之前有效,但是失败了现在:(请指教!
答案 0 :(得分:10)
FWIW
我从JDK1.6.0_33升级到1.7.0_21并遇到了同样的问题。我找到了这个document并通过启动rmiregistry解决了这个问题:
rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false
答案 1 :(得分:3)
所以,快速总结问题和解决方案:
如果您在JDK 7.1 / 6.29(可能是某些其他版本)上运行,则如果将其代码库设置为硬盘上的文件或目录,则RMI服务器将不会绑定。相同的代码在旧版本的JDK(在6.24上测试)下工作正常。 谢谢你的帮助!
答案 2 :(得分:2)
此处的根本问题是 RMI注册表在SecurityManager
下运行,而其 .policy文件未授予java.io.FilePermission" "\D:\uni\YEAR 3\Enterprise Programming\java\czat solution 2\bin\-" "read"
。
这样做的线索是,这是ServerException
,即在通话目标处抛出,并且通话本身是rebind()
。
请参阅this post以获取解释。
答案 3 :(得分:1)
是的,Java 1.7及更高版本中会出现此问题。因此,如果升级Java版本,请始终查看增强功能文档。这是一个相当简单的解决方案。您只需要以不同的方式启动rmiregistry
即可。
浏览此文档 - http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html
答案 4 :(得分:0)
您是否尝试使用* .policy文件明确授予对该文件的访问权限? 如上所述 http://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html
grant codebase "file:/path/to/code" { permission java.io.FilePermission "\D:\uni\YEAR 3\Enterprise Programming\java\czat solution 2\bin\-", "read"; }
我对openjdk也有同样的问题...可能是由于这个提交引起的: http://hg.openjdk.java.net/jdk7u/jdk7u-gate/jdk/rev/7ed2fd310470