我有使用jna Pointer类的applet。小程序代码是:
import com.sun.jna.*;
public class Applet1 extends Applet{
public void test() {
try {
Pointer p = new Memory(73);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在html代码中,我用这种方式声明了applet:
<applet
codebase=/pki/
code=Applet1.class
archive=/pki/jna-3.2.3.jar
id=Applet1
width=100
height=100 >
</applet>
当我通过javascript调用document.getElementById(“Applet1”)。test()时,会出现java.lang.reflect.InvocationTargetException。
我不能在java类中调用e.getCause(),因为applet try / catch不会捕获错误(我不明白为什么)。但javascript try / catch捕获此错误。
如果移动Pointer p = new Memory(73);
行,则可以。问题是这一行。
请帮助解决问题。
编辑:如果替换此块:
try {
Pointer p = new Memory(73);
} catch (Exception e) {
e.printStackTrace();
}
到
try {
Pointer p = new Memory(73);
} catch (Throwable e) {
System.out.println(e.getCause());
}
我收到java.security.AccessControlException:访问被拒绝(java.util.PropertyPermission jna.boot.library.path read)
答案 0 :(得分:7)
好的,现在我们来看问题的根源。 (你仍然可以使用printStackTrace
- 这也应该打印cause
的堆栈跟踪。)。
未签名的小程序只能访问有限数量的系统属性 - jna
属性不属于这些属性。
在未签名的applet中,无论如何都无法加载本机库,因此无法使用JNA(或顺便说一下JNI)。
如果您对applet进行签名(并告诉插件接受签名),则您的applet具有使用JNA的必要权限。但是,任何单个运行代码的权利实际上都是所有调用当前代码的方法的权利的交集。
从JavaScript调用的Applet方法具有极其有限的权限(因为如果您的浏览器甚至有这样的概念,插件无法真正检查JavaScript代码是否具有必要的权限。)
您可以通过使用AccessController.doPrivileged(...)
包装需要使用您的小程序权限运行的代码部分来解决此问题。但首先确保这不会做任何危险(使用JNI / JNA很容易),即使从恶意JavaScript代码调用也是如此。