我有一个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
而不是更具体的权限?
谢谢!
答案 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(并且您几乎从不需要)。