I'm looking at a signed Applet that is heavily called from JavaScript. Obviously, the threads that originate from JavaScript are more heavily sandboxed than any thread started directly from within Java. For example, if a JavaScript thread calls into the Applet and logs something that causes the log file to roll, a security exception is thrown. Any thread started directly within the Applet will not experience this security exception. The solution here with log4j is to use the asynchronous appender.
But with other security exceptions (for example making use of Apache Axis in the signed Applet but in a JavaScript thread) there is no obvious way to have some asynchronous thread. Let's say I have the following code that if called from a Java thread will work and if called via JavaScript will fail with a SecurityException:
public void someMethodCalledFromJavaScript() {
// Stuff that would throw a SecurityException
}
I see three following options, but they may not all be valid. For the sake of this discussion, ignore whether or not the execution will be synchronous or asynchronous, as that's easily managed. I am having a difficult time understanding the details of the security model. Here are my three potential choices:
Start a new Thread (will this one even work?):
public void someMethodCalledFromJavaScript() { new Thread(new Runnable() { public void run() { // Stuff that would throw a SecurityException } }).start(); }
Have the Applet have a thread ready to go at all times, triggered via the JavaScript-origin thread (highly simplified code here):
private volatile boolean doit = false; // This code is running in a Thread, started @ Applet init time public void alwaysWaiting() { while (true) { if (doit) { doit = false; // Stuff that would throw a SecurityException } } } public void someMethodCalledFromJavaScript() { doit = true; }
Use AccessController.doPrivileged:
public void someMethodCalledFromJavaScript() { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // Stuff that would throw a SecurityException return null; } }); }
According to what I read of AccessController.doPrivileged
, you run with the intersection of the current security privs and the privs of the security domain of the code you're calling. This doesn't make sense to me, as if you're running with the intersection of a low and a high security domain, you'll just have the low security domain. So clearly I'm not understanding something.
The specific SecurityException
I'm seeing is this one:
java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
but of course I'm curious about the general case in the context of JavaScript calling into a signed Applet, and how I can allow a JavaScript-originated thread to run with the priv's of the signed Applet as if it were a thread that originated purely within the Applet.
Which choices above will even work, and which are better than others, and why.