【问题标题】:java rmi : access control exception, access deniedjava rmi:访问控制异常,访问被拒绝
【发布时间】:2013-09-30 11:27:48
【问题描述】:

我正在浏览 sun 网站上的教程,尝试使用 RMI。

但是当我尝试启动服务器时,我得到了这个错误:

ComputeEngine exception:
java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372)
    at java.security.AccessController.checkPermission(AccessController.java:559)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
    at java.net.Socket.connect(Socket.java:574)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.<init>(Socket.java:425)
    at java.net.Socket.<init>(Socket.java:208)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at engine.ComputeEngine.main(ComputeEngine.java:31)

有人可以建议如何解决这个问题吗?我该如何摆脱这个异常,我该如何解决?

这是我得到异常的地方(我在该行右侧​​画了箭头):

package engine;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import compute.Compute;
import compute.Task;

public class ComputeEngine implements Compute {

    public ComputeEngine() {
        super();
    }

    public <T> T executeTask(Task<T> t) {
        return t.execute();
    }

    public static void main(String[] args) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        try {
            String name = "Compute";
            Compute engine = new ComputeEngine();
            Compute stub =
                (Compute) UnicastRemoteObject.exportObject(engine, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind(name, stub); <<<<<------
            System.out.println("ComputeEngine bound");
        } catch (Exception e) {
            System.err.println("ComputeEngine exception:");
            e.printStackTrace();
        }
    }
}

最后这就是我开始我的程序的方式:

我将在下面留下可能有用的更多相关信息:

这是文件 ~/.server_policy:

grant codeBase "file:/home/jenia/Documents/eclipse/workspace/asti01/bin" {
    permission java.security.AllPermission;
};

这是项目目录的树:

/home/jenia/Documents/eclipse/workspace/asti01$ tree
.
├── bin
│   ├── client
│   │   ├── ComputePi.class
│   │   └── Pi.class
│   ├── compute
│   │   ├── Compute.class
│   │   └── Task.class
│   └── engine
│       └── ComputeEngine.class
└── src
    ├── client
    │   ├── ComputePi.java
    │   └── Pi.java
    ├── compute
    │   ├── Compute.java
    │   └── Task.java
    ├── compute.jar
    └── engine
        └── ComputeEngine.java

这是文件夹的树 ~/public_html

/home/jenia/public_html/
└── classes
    ├── client
    │   └── Pi.class
    └── compute.jar

【问题讨论】:

  • RMI 中的 EOFException 通常是由另一端的 SecurityManager 问题引起的。你可以在没有代码库和安全管理器的情况下尝试吗?
  • 我不明白你的意思
  • 如果您不理解“没有代码库和安全管理器”,我无法进一步帮助您解决旧问题。您的新问题完全不同:见下文。
  • 好的,我解决了这个问题。你认为是什么问题?为什么会出现异常?
  • 'Fixed'?你已经完全改变了它。它一开始是 EOFException;然后它变成了一个 ConnectException;现在它是一个 AccessControlException。毫无疑问,当你过去时,你会再次改变它。这太疯狂了。

标签: java eclipse rmi javac


【解决方案1】:

如果您的 RMI 注册服务器在 Localhost 中运行,那么您应该使用 127.0.0.1 而不是 127.0.1.1

启动ComputePi时传入127.0.0.1

【讨论】:

  • 对不起,我不明白。通过它在哪里?当我在shell中执行命令时?如果有,怎么做?
  • 您不知道自己是如何运行自己的程序的?
  • 不,我愿意。我不知道如何将参数传递给程序和 java 虚拟机。但现在我正在使用 eclipse 并且有为此的文本字段。但我仍然遇到同样的错误(在 ip 127.0.0.1 上)
  • 另一个错误比如什么?这个问题越来越荒谬了。
【解决方案2】:
  1. 原始问题的答案是 RMI 中的 EOFException 通常是由另一端的 SecurityManager 问题引起的。在没有代码库和安全管理器的情况下尝试。

  2. 您的问题的第二个版本的答案是注册表没有运行,并且 getRegistry() 没有启动它。 createRegistry() 可以。

  3. 第三版问题的答案与第一版相同。

  4. 当您通过这一切进入下一个错误(绑定时无疑是ClassNotFoundException)时,解决方案是使用正确的类路径运行注册表。

  5. 当您越过那个到下一个错误时,查找时无疑是ClassNotFoundException,解决方案是运行客户端正确的类路径。

【讨论】:

  • 为了清楚起见并为将来的读者提供帮助,这就是您第二个问题的答案。你现在至少达到了第三个。奇怪的是,我最初关于删除安全管理器和代码库的评论仍然适用。
【解决方案3】:

重申@EJP 的原始评论:

忽略教程中与配置/使用 SecurityManager 相关的所有内容。不要尝试使用远程代码加载。这些“功能”大大增加了使用 rmi 的复杂性,并且 99% 的用户实际上并不需要它们

【讨论】:

  • 我完全同意。可悲的是,我在几个小时前说了同样的话,但没有任何效果。
  • @EJP - 哈,看到了你的答案,但没有通读 OP 上的所有 cmets。已更新。
猜你喜欢
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 2012-10-17
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多