为什么缺少Java权限会有NPE?以及如何找出哪个权限?

时间:2014-09-16 11:59:48

标签: java security permissions applet event-dispatch-thread

我有一个Java Applet,在permission java.security.AllPermission;文件中授予java.policy后运行正常。

但我真的只想设置我的应用程序所需的一个权限 - 所以我删除了策略文件中的行permission java.security.AllPermission;,期望拒绝访问异常或其他内容,但我得到的是以下代码中的NullPointerException:

protected Object[] __ObjectArrayResult;

(...)

final Container c = (Container) container;

        InvocationWrapper.invokeAndWait(new Runnable() {
            public void run() {
                __ObjectArrayResult = c.getComponents();
            }
        });

        Object[] components = __ObjectArrayResult;

        Vector componentVector = Utils.convertArrayToVector(components);

我在这里尝试的是获取AWT容器的所有Conponents,但c.getComponents();返回Null,而Utils.convertArrayToVector(components);抛出NPE。

那么为什么getComponents方法(如果它需要一些特殊的Permission)不抛出异常而只返回Null?我查看了文档,但没有提到任何案例,这将返回Null。


我尝试过的下一件事是调试权限。使用这种方法,我发现了这个: http://docs.oracle.com/javase/7/docs/technotes/guides/security/troubleshooting-security.html

其中声明-Djava.security.debug=access可用于查看AccessController.checkPermission的所有结果

但是运行它只是给了我以下内容:

access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
access: access allowed ("java.util.PropertyPermission" "line.separator" "read")
access: access denied ("java.security.AllPermission" "<all permissions>" "<all actions>")
Exception in thread "Thread-19" access: access allowed ("java.lang.RuntimePermission" "modifyThread")
access: access allowed ("java.io.SerializablePermission" "enableSubstitution")
java.lang.NullPointerException: Utils::convertArrayToVector - Array is NULL!

我不知道该怎么做。它说AllPermissions被拒绝,这是否意味着某些方法要求AccessController获取所有权限?或者是否首先尝试获得更一般的权限"java.lang.RuntimePermission" "modifyThread"来获取allPermission


总结一下:为什么getComponents()返回Null?为什么它不抛出异常并告诉我需要哪个权限?为什么要求AllPermission而不是更具体的权限?

谢谢!

1 个答案:

答案 0 :(得分:2)

修复您对EDT的调用,不要吞下异常:

    final Container c = (Container) container;
    final AtomicReference<Object[]> result = new AtomicReference<>();
    try {
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                result.set(c.getComponents());
            }
        });
    } catch (Exception e) {
         throw new RuntimeException(e.getMessage(), e);
    }
    Object[] components = result.get();
    Vector componentVector = Utils.convertArrayToVector(components);

您现在可以查看您的代码未能错过权限的位置。

您还注意到,使用 local 引用(结果)可以安全地在Runnable和调用线程之间交换值。通过实例成员执行此操作是非常糟糕的样式,如果在多个线程可以同时执行runnable的上下文中使用,则会彻底破坏。

另外值得注意的是,Vector几乎永远不会你想要使用什么(因为Vector是同步的)。当您不需要同步访问时切换到ArrayList(并且您几乎从不需要)。