[英]Why is there a NPE on a missing Java Permission? And how to find out which Permission?
I have a Java Applet, that runs fine when permission java.security.AllPermission;
我有一个Java Applet,当permission java.security.AllPermission;
时运行良好permission java.security.AllPermission;
is granted in the java.policy
file. 在java.policy
文件中被授予。
But I really just want to set the one permission needed for my Application - so I deleted the line permission java.security.AllPermission;
但是我真的只想为我的应用程序设置一个权限-所以我删除了行permission java.security.AllPermission;
in the policy file, expecting an Access Denied Exception or something along those lines, but all I get is a NullPointerException at the following Code: 在策略文件中,期望访问被拒绝的异常或类似的内容,但是我得到的只是以下代码中的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);
What I am trying here, is to get all the Conponents of a AWT Container, but c.getComponents();
我在这里尝试的是获取AWT容器的所有组件,但是c.getComponents();
returns Null, and the Utils.convertArrayToVector(components);
返回Null,以及Utils.convertArrayToVector(components);
throws the NPE. 抛出NPE。
So why does the getComponents method (if it needs some special Permission) not throw an exception and just return Null? 那么,为什么getComponents方法(如果需要一些特殊的权限)不抛出异常而只返回Null? I looked through the Documentation, but no case is mentioned, which would return Null. 我浏览了文档,但没有提到任何情况,它将返回Null。
The next thing I've tried is to Debug the Permissions. 我尝试的下一件事是调试权限。 Using that approach, I found this: http://docs.oracle.com/javase/7/docs/technotes/guides/security/troubleshooting-security.html 使用这种方法,我发现了这一点: http : //docs.oracle.com/javase/7/docs/technotes/guides/security/troubleshooting-security.html
Where it states that -Djava.security.debug=access
could be used to see all the Results of AccessController.checkPermission
它指出-Djava.security.debug=access
可用于查看AccessController.checkPermission
所有结果
But running that just gave me the following: 但是运行该命令给了我以下几点:
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!
I have no clue what to make of this. 我不知道该怎么做。 It says that AllPermissions
is denied, does this mean that some Method Asks the AccessController
for all the Permissions? 它说AllPermissions
被拒绝,这是否意味着某个方法向AccessController
询问所有的权限? or is it trying to get "java.lang.RuntimePermission" "modifyThread"
by first trying to get the more general permission allPermission
? 还是通过首先尝试获取更通用的权限allPermission
来获取"java.lang.RuntimePermission" "modifyThread"
?
So to summarize: Why is getComponents()
returning Null? 总结一下:为什么getComponents()
返回Null? Why does it not throw an Exception and tell me which Permission is needed? 为什么不抛出异常并告诉我需要哪个权限? Why is AllPermission
requested instead of a more specific permission? 为什么要求AllPermission
而不是更具体的权限?
Thanks! 谢谢!
Fix your invocations of the EDT not to swallow exceptions: 修正对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);
You will now be able to see where your code fails missing a permission. 现在,您将能够看到代码在缺少权限的地方失败的地方。
You also note that exchanging a value between Runnable and invoking thread is done safely using a local reference (result). 您还注意到,使用本地引用(结果)可以安全地在Runnable和调用线程之间交换值。 Doing this through an instance member is extremely bad style, and outright broken if used in a context where more than one thread could execute the runnable concurrently. 通过实例成员执行此操作非常糟糕,如果在多个线程可以同时执行可运行对象的上下文中使用,则将彻底中断。
Its also notable that Vector is almost never what you want to use (because Vector is synchronized). 同样值得注意的是,Vector几乎永远不会是您想要使用的(因为Vector已同步)。 Switch to ArrayList when you don't need synchronized access (and you almost never need that). 切换到ArrayList的,当你不需要同步访问(和你几乎不必说)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.