java.security.AccessControlException 가 throw 된다 ... - xrath.com 에서 번역됨

> ## `java.security.AccessControlException` 가 `java.lang.Thread` 의 `stop`,`suspend`, 또는 `resume` 메소드로 throw 된다

> ###
> 증상

> > 애플릿을 Sun JRE 를 사용한 브라우저로 실행하고 있는 경우,`AccessControlException` 가 `java.lang.Thread` 의 `stop`,`suspend`, 또는 `resume` 메소드로 throw 됩니다.
> > `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 ....`
> > 같은 애플릿이 Microsoft VM 에서는 실행할 수 있습니다.

> ### 원인

> > 이 예외는, Sun JRE 로 이러한 메소드가 죽어 있는 `Thread` 객체상에서 불려 가기 위해서(때문에) 일어납니다.
> > Sun JRE 의 Java 클래스 라이브러리는 시간의 경과와 함께 변화해 왔습니다. 상세하게 된 API 도 있으면, 폐지된 API 도 있습니다. 또, 구현이 변경된 API 도 있습니다.

> > `stop`,`suspend`, 및 `resume` 를 죽어 있는 `Thread` 객체상에서 호출했을 경우의 결과는 상세하게 정의되어 있지 않았기 (위해)때문에, Microsoft VM 에서는 무조작이 됩니다. 그러나 Sun JRE 에서는 이러한 메소드를 죽어 있는 `Thread` 객체로 호출하면(자), 기초가 되는 구현의 불변 부분이 의미를 만들어내지 않게 되기 (위해)때문에,`AccessControlException` 가 throw 됩니다.

> ### 해결 방법

> `Thread` 의 `stop`,`suspend`, 및 `resume` 메소드는 본질적으로 안전하지 않기 때문에, Java 플랫폼에서는 폐지되었습니다.

> 이 문제를 회피하려면 , 타겟 thread가 정지·중단·재개하는 것을 나타내는 변수를 변경하는 코드로,`stop`,`suspend`, 및 `resume` 의 호출을 옮겨놓습니다.
> 예를 들어, 애플릿에 다음의 메소드가 포함되어 있다고 합니다.

>         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();
>             }
>         }

> 애플릿의 `stop`,`destroy`, 및 `run` 메소드를 다음의 코드로 옮겨놓으면,`Thread.stop` 를 사용하지 않고 끝납니다.

>         private volatile Thread blinker;

>         public void stop() {
>             blinker = null;
>         }

>         public void destroy() {
>             blinker = null;
>         }

>         public void run() {
>             Thread thisThread = Thread.currentThread();
>             while (blinker == thisThread) {
>                 try {
>                     thisThread.sleep(interval);
>                 } catch (InterruptedException e){
>                 }
>                 repaint();
>             }
>         }

> 다른 예:애플릿에 다음과 같은 `mousePressed` 이벤트 핸들러가 포함되어 있어 그것이 `blinker` 라고 하는 thread 상태를 바꾼다고 합니다.

>         private boolean threadSuspended;

>         public void mousePressed(MouseEvent e) {
>             e.consume();

>             if (threadSuspended)
>                 blinker.resume();
>             else
>                 blinker.suspend();  // DEADLOCK-PRONE!

>             threadSuspended = ! threadSuspended;
>         }

>         public void run()
>         {
>     	 while (true) {
>             try {
>                 Thread.currentThread(). sleep(interval);
>             } catch (InterruptedException e){
>             }
>             repaint();
>         }

> 위의 이벤트 핸들러를 다음의 코드로 옮겨놓으면(자),`Thread.suspend` 및 `Thread.resume` 를 사용하지 않아도 됩니다.

>         private boolean volatile threadSuspended;

>         public synchronized void mousePressed(MouseEvent e) {
>             e.consume();

>             threadSuspended = ! threadSuspended;

>             if (! threadSuspended)
>                 notify();
>         }

>         public void run() {
>             while (true) {
>                 try {
>                     Thread.currentThread(). sleep(interval);

>                     if (threadSuspended) {
>                         synchronized(this) {
>                             while (threadSuspended)
>                                 wait();
>                         }
>                     }
>                 } catch (InterruptedException e){
>                 }
>                 repaint();
>             }
>         }

> ### 상세 정보

> > `Thread.stop`,`Thread.suspend`,`Thread.resume`, 및 `Runtime.runFinalizersOnExit` 가 추천 되지 않는 이유