【问题标题】:Java RMI cannot bind serverJava RMI 无法绑定服务器
【发布时间】:2011-11-16 19:09:06
【问题描述】:

我正在开发 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 插件提供的“从类路径计算”选项,该选项以前有效,但失败了现在:(请指教!

【问题讨论】:

  • 您是否尝试过不设置“RMISecurityManager”?
  • 用-Djava.security.debug=access,failure 运行它,看看有没有什么东西跳到你身上
  • 是的,我在 Windows 7 上,当我在没有安全管理器的情况下运行它时,它给了我:拒绝访问 ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve ") java.security.AccessControlException: 访问被拒绝 ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve") 在 java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
  • 它说:-Djava.security.debug 不被识别为内部或外部命令...
  • @tomsky 如果你得到AccessControlExceptions,你肯定是在SecurityManager 的控制之下,不管你是否这么认为。 -Djava.security.debug=access,failure 是 java 命令的参数,而不是它自己的命令。

标签: java rmi


【解决方案1】:

FWIW

我从 JDK1.6.0_33 升级到 1.7.0_21 也遇到了同样的问题。我找到了这个document 并通过启动 rmiregistry 解决了这个问题:

rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false

【讨论】:

    【解决方案2】:

    所以,快速总结一下问题和解决方案:

    如果您在 JDK 7.1/ 6.29(可能是其他版本)上运行,如果您将其代码库设置为硬盘上的文件或目录,RMI 服务器将不会绑定。相同的代码在旧版本的 JDK 下工作得很好(在 6.24 上测试)。 感谢您的帮助!

    【讨论】:

    • 问题出在 RMI 注册表和 file: 代码库上。
    【解决方案3】:

    这里的根本问题是 RMI 注册表 在 SecurityManager 下运行,而 其 .policy 文件不授予 java.io.FilePermission" "\D:\uni\YEAR 3\Enterprise Programming\java\czat solution 2\bin\-" "read"。

    这方面的线索是这是一个ServerException,即向调用的目标抛出,而调用本身是rebind()。

    请参阅this post 了解说明。

    【讨论】:

    • 谢谢,这解释了很多。在我的情况下,最简单的事情就是使用旧版本的 JDK。
    【解决方案4】:

    是的,Java 1.7 及更高版本中会出现此问题。因此,如果您升级 Java 版本,请务必阅读增强文档。这是一个相当简单的解决方案。您只需要以不同的方式启动rmiregistry。

    浏览此文档-http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html

    【讨论】:

      【解决方案5】:

      您是否尝试过使用 *.policy 文件明确授予对该文件的访问权限? 如上所述 http://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html

      授予代码库“文件:/路径/到/代码”{ 权限 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-06
        • 2015-07-04
        • 1970-01-01
        相关资源
        最近更新 更多