简体   繁体   English

java rmi:访问控制异常,访问被拒绝

[英]java rmi : access control exception, access denied

I'm going through the tutorial at sun's website, try to use RMI. 我正在浏览sun的网站上的教程,尝试使用RMI。

But when I try to start the server I get this error: 但是当我尝试启动服务器时,我收到此错误:

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)

Can someone advice on how to remedy this? 有人可以建议如何解决这个问题吗? How do I get rid of this exception, how do i fix it? 我如何摆脱这个异常,我该如何解决?

This is where i get the exception (where i drew the arrow on the right of the line): 这是我得到异常的地方(我画了右边的箭头):

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();
        }
    }
}

and finally this is how i start my program: 最后这就是我开始我的程序的方式:

程序和jvm的参数

I'll leave further pertinent information that may be of use underneath: 我将在下面留下可能有用的更多相关信息:

This is the file ~/.server_policy: 这是〜/ .server_policy文件:

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

This is the tree of the project directory: 这是项目目录的树:

/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

this is the tree of the folder ~/public_html 这是〜/ public_html文件夹的树

/home/jenia/public_html/
└── classes
    ├── client
    │   └── Pi.class
    └── compute.jar
  1. The answer to your original question is that EOFException in RMI usually results from a SecurityManager problem at the other end. 原始问题的答案是RMI中的EOFException通常是由另一端的SecurityManager问题引起的。 Try it without the codebase and security managers. 在没有代码库和安全管理器的情况下尝试它。

  2. The answer to the 2nd version of your question is that the Registry isn't running, and getRegistry() doesn't start it. 您的问题的第二个版本的答案是注册表未运行,并且getRegistry()不启动它。 createRegistry() does. createRegistry()可以。

  3. The answer to the third version of your question is the same as to the first version. 您的问题的第三个版本的答案与第一个版本的答案相同。

  4. When you get past all this to the next error, which will undoubtedly be ClassNotFoundException when binding, the solution is to run the Registry with the correct classpath. 当你通过所有这些到下一个错误时,绑定时无疑是ClassNotFoundException ,解决方案是使用正确的类路径运行Registry。

  5. When you get past that to the next error, which will undoubtedly be ClassNotFoundException when looking-up, the solution is to run the client with the correct classpath. 当你过去下一个错误,这无疑将成为ClassNotFoundException寻找行动的时候,解决的办法是用正确的类路径运行客户端

To reiterate @EJP's original comment: 重申@ EJP的原始评论:

Ignore everything in the tutorial related to configuring/using a SecurityManager. 忽略教程中与配置/使用SecurityManager相关的所有内容。 Don't attempt to use remote code loading. 不要尝试使用远程代码加载。 These "features" greatly increase the complexity of using rmi and 99% of users don't actually need them . 这些“功能”大大增加了使用rmi的复杂性,99%的用户实际上并不需要它们

If your RMI Registry Server is running in Localhost then you should use 127.0.0.1 not 127.0.1.1 如果您的RMI Registry Server在Localhost中运行,那么您应该使用127.0.0.1而不是127.0.1.1

Pass in 127.0.0.1 when starting ComputePi 启动ComputePiComputePi 127.0.0.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM