【问题标题】:Java RMI AccessControlException: access deniedJava RMI AccessControlException:访问被拒绝
【发布时间】:2011-01-26 12:22:00
【问题描述】:

嘿,我在尝试启动我正在编写的 RMI 应用程序时收到 AccessControlException: access denied,如果我在默认端口 1099 或另一个动态端口上打开它,我无法弄清楚为什么会出现此异常端口,我的策略文件目前授予一切(应用程序完成后将更改)。

我不知道哪里出了问题,任何帮助都会很有用

我的代码

public class Main {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
     if (System.getSecurityManager() == null)
     {
        System.setSecurityManager ( new RMISecurityManager() );
     }

     CreditCardServer ccs = new CreditCardServer();

     int port = 1099;

     try {
        port = Integer.valueOf(args[0]);
        }
     catch (Exception e)
        {
        System.out.println("Invlaid Port");
        }

     if (((port <= 65535) && (port >= 49152)) || port ==1099)
     {
     System.out.println("Valid Port");
     }
     else
     {
         port = 1099;
        System.out.println("Port not in Dynamic Range 49152<-->65535");
     }

     System.out.println(port);

     LocateRegistry.createRegistry(port);

     LocateRegistry.getRegistry().bind("CreditCardServer", ccs);

     while (true)
     {
        //hum?
     }
}

}

堆栈跟踪

vega3 [ia32.linux] 23% java -Djava.security.policy=wideopen.policy -jar "BookStore-CreditCardServer.jar 65000"

有效端口

65000

Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
        at java.security.AccessController.checkPermission(AccessController.java:553)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
        at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
        at java.net.Socket.connect(Socket.java:536)
        at java.net.Socket.connect(Socket.java:492)
        at java.net.Socket.<init>(Socket.java:389)
        at java.net.Socket.<init>(Socket.java:203)
        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.bind(Unknown Source)
        at bookstorecreditcardserver.Main.main(Main.java:56)

我的政策文件

grant {
// Allow everything for now
permission java.security.AllPermission;
};

【问题讨论】:

  • 你能不能在你的机器上做一个 nmap 来确保没有东西在使用那个端口(例如,你之前运行过这个程序并且它没有干净地死掉)。

标签: java rmi accesscontrolexception


【解决方案1】:

基本上,我很愚蠢,我认为因为 Java 没有抱怨它正在寻找 .policy 文件 AOK,结果证明它没有将 .policy 文件的新副本移动到工作目录中解决了所有问题:-D

【讨论】:

    【解决方案2】:

    我整天都被困在这个问题上(在弄清楚我必须从命令行启动 rmiregistry 之后),试图用 Eclipse 在本地进行这项工作,并最终解决了它。拯救他人这种残酷命运的几点建议:

    1 - 使用命令行标志正确分配策略文件:

    java -Djava.security.policy=/home/.../<filename>.policy ...
    

    或将其直接放入您的代码中:

    System.setProperty("java.security.policy","file:///home/.../<filename>.policy");
    

    你也可以把它和你的项目根目录放在同一个文件夹),以减少URI到

    file:./<filename>.policy
    

    (使用相对而不是绝对 URI - 实际上直到今天我才明白这一点)。

    2 - 确保策略文件的格式正确,例如:

    grant codeBase "file:<path>/bin/-" {
        permission java.security.AllPermission;
    };
    

    这应该是指您的二进制文件所在的文件夹!策略文件格式的详尽解释是here

    就是这样,我也推荐this tutorial,我发现这对走上正轨很有帮助。

    【讨论】:

    • +1 感谢您对这个古老但仍然非常有效的问题的广泛回答 Nauta & wecome。
    • 策略文件链接格式的解释已经过时了。
    • 如何获得security.policy 文件的正确路径?
    【解决方案3】:

    我发现关于这个主题的大多数答案都含糊不清且没有帮助,因此我花了几个小时进行调试。您的错误很可能是因为策略文件的格式不正确,或者您没有将其正确设置为命令行参数。

    如果您收到java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")

    1. 创建一个具有所有权限的安全策略文件,只是为了测试一下

    grant codeBase "file:/-" { permission java.security.AllPermission; };

    1. 将此安全文件用于客户端和服务器,只是为了让它运行。

    2. 确保没有任何拼写错误。我花了几个小时试图弄清楚为什么它不起作用,我输入了 -Djava.rmi.security.policy 而不是 -Djava.security.policy=...

    对于我们这些只想启动并运行 Oracle 的 RMI 教程的人来说,这个安全策略对于该示例来说已经绰绰有余了。

    【讨论】:

    • 您的回答与六年前发布的this one 基本相同,既不含糊也不无用。否则你的也是。
    • 花了几个小时调试这个,我可以向你保证,这个问题需要更多的答案。我发现这一行特别广泛地使问题“这应该指的是你的二进制文件所在的文件夹!”
    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2015-01-21
    • 2013-11-18
    • 2013-09-30
    相关资源
    最近更新 更多