我有使用jna指针类的小程序。小程序代码为:

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
    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)。

评论

尝试使用catch(Throwable e)代替catch(Exception e)。也许您在这里遇到一些错误而不是一个异常,该异常将被JavaScript桥包装在您的InvocationTargetException中。.

@PaŭloEbermann:你很严厉。这是一个Throwable实例。谢谢。现在我知道发生了什么。

实际上,它很可能是Error的某些子类的实例(Throwable是Error和Exception的超类,并且几乎从未使用过。)

#1 楼

好的,现在我们来探究问题的根源。 (您仍然可以使用printStackTrace-这也应该已经打印了cause的堆栈跟踪。)


未签名的小程序只能访问有限的系统属性-jna属性不属于这些属性。
在未签名的applet中,无论如何您都无法加载本机库,因此无法使用JNA(或JNI)。

如果您进行签名小程序(并告诉插件接受签名),您的小程序具有使用JNA的必要权利。但是任何运行代码的权限实际上就是调用当前代码的所有方法的权限的交叉点。

从JavaScript调用的Applet方法具有非常有限的权限(因为插件无法真正检查如果您的浏览器甚至具有这样的概念,则JavaScript代码具有必要的权限。)

您可以通过包装部分代码来解决此问题,该代码部分需要使用applet的权限来运行, AccessController.doPrivileged(...)。但是首先要确保它不会做任何危险的事情(对于JNI / JNA来说很容易),即使是从恶意JavaScript代码中调用也是如此。