java.security.AccessControlException thrown
in stop, suspend, or resume method
of java.lang.Thread
Symptoms
When running an applet in a browser using the Sun JRE, an AccessControlException
is thrown in the stop, suspend, or resume
method of java.lang.Thread.
java.security.AccessControlException:
access denied (java.lang.RuntimePermission modifyThread)
at java.security.AccessControlContext.checkPermission(Unknown
Source)
at java.security.AccessController.checkPermission(Unknown
Source)
at java.lang.SecurityManager.checkPermission(Unknown
Source)
at sun.applet.AppletSecurity.checkAccess(Unknown
Source)
at java.lang.Thread.checkAccess(Unknown
Source)
at java.lang.Thread.stop(Unknown
Source)
at ....
The same applet runs under the Microsoft VM.
Cause
This exception is caused by calling these methods on a dead Thread
object in the Sun JRE.
The Java class libraries in the Sun JRE have changed over time. Some APIs
have been clarified, some have been deprecated, and some have had their
implementation altered.
The result of calling stop, suspend, and resume
on a dead Thread object was not well defined. In the Microsoft
VM, they result in a no-op. However, in the Sun JRE, calling these methods
on a dead Thread object invalidates the underlying invariant
of the implementation, thus resulting in an AccessControlException.
Resolution
The Threadstop, suspend, and resume
methods are inherently unsafe and have been deprecated in the Java 2 platform.
To work around this problem, replace calls to stop, suspend,
and resume with code that simply modifies some variable to indicate
that the target thread should stop/suspend/resume.
For example, suppose your applet contains the following methods:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void destroy() {
blinker.stop(); // UNSAFE and WILL throw AccessControlException in the Sun JRE!
}
public void run() {
Thread thisThread = Thread.currentThread();
while (true) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's
stop, destroy, and run methods with: