这将是一个很难解释,但如果有人有任何指针,请分享!
从applet我调用第三个使用JNI的奇偶校验库,以特定于操作系统的方式获取一些信息。我不知道它叫什么,因为我没有代码和支持不是很敏感。 问题是,所有这些都适用于Windows(不仅仅是我的机器),但在Mac OS上,其中一个lib的方法会引发特定于lib的异常(代码和“无法完成”消息)。这似乎是一个与安全相关的问题,因为当我从init()中调用它时,该方法可以正常工作。
我的applet的jar是自签名的,该库还有4个由供应商签名的jar。从“AccessController.doPrivileged”块中调用lib的方法作为从JavaScript调用的applet方法 - 这一切都有效,但仅限于Windows。
在Mac上,这种从JavaScript到调用lib方法的applet方法的调用会获得异常。
以下是我的尝试:
我在init()中移动了lib的方法调用,仅用于测试,它运行正常,只有没有“AccessController.doPrivileged”块。 我尝试在init()中启动一个Thread(在start()中也是如此): - 使用一个计时器让线程调用lib的方法每10秒工作正常,我可以得到更新的回复槽一个字符串缓冲区 - 这不是一个首选的解决方案。 - 但是如果我在线程中使用了一个标志,以便applet方法可以返回结果,则会抛出相同的异常。
以下是我的applet方法中的代码:
checkRunner.refreshWindowsList = true;
while (checkRunner.refreshWindowsList) {
try {
Thread.sleep(300);
} catch (Exception ex) {
System.out.println("Ignoring exception: " + ex.getMessage());
}
}
return checkRunner.windowsTitles;
并在Thread的run方法中:
try {
while (true) {
if (refreshWindowsList) {
windowsTitles = getWindowsTitlesPrivileged();
//windowsTitles = getWindowsTitles();
refreshWindowsList = false;
}
Thread.sleep(300);
}
} catch (Exception ex) {
System.out.println("Ignoring exception: " + ex.getMessage());
}
我不明白传递旗帜会导致不同的结果。
此外,似乎当从JavaScript代码创建applet时,所有这些都是沙箱,而lib的方法甚至从init()再次抛出异常......仅在Mac OS上。
如果有人做到这一点 - 谢谢你:)
答案 0 :(得分:0)
回答我的问题,甚至认为我非常怀疑这是一个常见的问题......
事实证明,这个问题毕竟与安全无关。问题的起源是因为第三个奇偶校验库的一个非常难以理解的行为 - 每当调用有问题的方法时,即使在一个单独的线程中,在主线程中它们也是一个等待答案的循环 - 异常是抛出。
所以下面的代码失败了,但是当最后的睡眠行被删除时,它可以正常工作。无论代码在哪里,init()或从JavaScript调用的方法都会发生这种情况 - 行为是相同的。
new Thread(new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
callTheMehod();
}
});
}
}).start();
try { Thread.sleep(5000); } catch (exce....) {}
我最终将代码拆分为两个从JavaScript调用的方法 - 一个调用库方法,将结果放在一个易变的String中,另一个只返回这个易变的String。在JavaScript中,它们是两者之间的等待循环。奇怪的是,如果这个循环的间隔非常短 - 并且检查结果的方法经常被调用,那么库方法会再次失败。
因此,只要主线程上有太多负载,就会抛出异常。这对我来说是莫名其妙的,但由于图书馆正在使用JNI,我猜这可能会出错。