这将是一个很大的混乱来解释,但如果谁有任何指针,请分享!
从applet我调用第三奇偶校验库,它使用JNI以特定的操作系统方式获取一些信息。我不知道它叫什么,因为我没有代码,支持也不是很灵敏。问题是,所有这些都在windows上运行良好(不仅仅是我的机器),但在Mac OS上,lib的一个方法抛出了一个lib特定的异常(一个代码和一个"Cannot complete"~消息)。这似乎是一个安全相关的问题,因为当我从init()中调用它时,该方法可以工作。
我的applet的jar是自签名的,库中有4个以上的jar是由供应商签名的。lib的方法是从"AccessController"中调用的。"doPrivileged"块作为从JavaScript调用的applet方法-这一切都有效,但仅在windows上。
在Mac上,从JavaScript调用调用lib方法的applet方法会得到异常。
这是我尝试的:
我在init()中移动了lib的方法调用,只是为了测试,它工作正常,只有没有一个"AccessController"。doPrivileged"块中。我尝试在init()中启动一个线程(在start()中也是如此):-使用计时器让线程调用库的方法每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());
}
我不明白为什么仅仅传递一个标志就会导致不同的结果。
此外,似乎当applet从JavaScript代码中创建时,所有它都是沙盒的,lib的方法抛出异常,甚至从init()…
如果有人能走到这一步-谢谢:)
回答我的问题,即使我高度怀疑这是一个普遍的问题…
事实证明,这个问题与安全无关。这个问题源于第三奇偶校验库的一个相当莫名其妙的(对我来说)行为——每当调用有问题的方法时,即使在单独的线程中,并且在主线程中它们是一个等待答案的循环——抛出异常。
所以下面的代码失败了,但是当最后的睡眠行被删除时,它工作正常。无论代码在哪里,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,我猜是很多可能出错的