changeset 9733:aee0fdff54d4

8031477: [macosx] Loading AWT native library fails 8002191: AWT-Shutdown thread does not start with the AppletSecurity on Linux 8031032: SQE test failures after JDK-8025010 was fixed Reviewed-by: serb, ddehaven
author pchelko
date Wed, 15 Jan 2014 11:53:54 +0400
parents d23dfb999f5b
children 76a17befc935
files src/macosx/classes/sun/font/CFontManager.java src/macosx/classes/sun/lwawt/LWToolkit.java src/macosx/native/sun/awt/awt.m src/macosx/native/sun/osxapp/ThreadUtilities.h src/macosx/native/sun/osxapp/ThreadUtilities.m src/share/classes/java/awt/EventQueue.java src/share/classes/sun/awt/AWTAutoShutdown.java src/share/classes/sun/awt/SunToolkit.java src/share/classes/sun/font/CreatedFontTracker.java src/share/classes/sun/font/SunFontManager.java src/share/classes/sun/java2d/Disposer.java src/share/classes/sun/java2d/opengl/OGLRenderQueue.java src/share/classes/sun/misc/ThreadGroupUtils.java src/solaris/classes/sun/awt/X11/XToolkit.java src/solaris/classes/sun/awt/X11GraphicsDevice.java src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java src/windows/classes/sun/awt/windows/WToolkit.java src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java test/java/awt/Toolkit/LoadAWTCrashTest/LoadAWTCrashTest.java
diffstat 19 files changed, 261 insertions(+), 246 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/font/CFontManager.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/macosx/classes/sun/font/CFontManager.java	Wed Jan 15 11:53:54 2014 +0400
@@ -27,6 +27,8 @@
 
 import java.awt.*;
 import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -38,6 +40,7 @@
 
 import sun.awt.FontConfiguration;
 import sun.awt.HeadlessToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.lwawt.macosx.*;
 
 public class CFontManager extends SunFontManager {
@@ -215,24 +218,19 @@
                                 });
                     }
                 };
-                java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedAction<Object>() {
-                            public Object run() {
-                                /* The thread must be a member of a thread group
-                                 * which will not get GCed before VM exit.
-                                 * Make its parent the top-level thread group.
-                                 */
-                                ThreadGroup tg =
-                                    Thread.currentThread().getThreadGroup();
-                                for (ThreadGroup tgn = tg;
-                                tgn != null;
-                                tg = tgn, tgn = tg.getParent());
-                                fileCloser = new Thread(tg, fileCloserRunnable);
-                                fileCloser.setContextClassLoader(null);
-                                Runtime.getRuntime().addShutdownHook(fileCloser);
-                                return null;
-                            }
-                        });
+                AccessController.doPrivileged(
+                        (PrivilegedAction<Void>) () -> {
+                            /* The thread must be a member of a thread group
+                             * which will not get GCed before VM exit.
+                             * Make its parent the top-level thread group.
+                             */
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            fileCloser = new Thread(rootTG, fileCloserRunnable);
+                            fileCloser.setContextClassLoader(null);
+                            Runtime.getRuntime().addShutdownHook(fileCloser);
+                            return null;
+                        }
+                );
                 }
             }
         }
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Jan 15 11:53:54 2014 +0400
@@ -35,6 +35,7 @@
 
 import sun.awt.*;
 import sun.print.*;
+import sun.misc.ThreadGroupUtils;
 
 import static sun.lwawt.LWWindowPeer.PeerType;
 
@@ -70,30 +71,17 @@
     protected final void init() {
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
-        ThreadGroup mainTG = AccessController.doPrivileged(
-            new PrivilegedAction<ThreadGroup>() {
-                public ThreadGroup run() {
-                    ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = currentTG.getParent();
-                    while (parentTG != null) {
-                        currentTG = parentTG;
-                        parentTG = currentTG.getParent();
-                    }
-                    return currentTG;
-                }
-            }
-        );
+        ThreadGroup rootTG = AccessController.doPrivileged(
+                (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
 
         Runtime.getRuntime().addShutdownHook(
-            new Thread(mainTG, new Runnable() {
-                public void run() {
-                    shutdown();
-                    waitForRunState(STATE_CLEANUP);
-                }
+            new Thread(rootTG, () -> {
+                shutdown();
+                waitForRunState(STATE_CLEANUP);
             })
         );
 
-        Thread toolkitThread = new Thread(mainTG, this, "AWT-LW");
+        Thread toolkitThread = new Thread(rootTG, this, "AWT-LW");
         toolkitThread.setDaemon(true);
         toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
         toolkitThread.start();
--- a/src/macosx/native/sun/awt/awt.m	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/macosx/native/sun/awt/awt.m	Wed Jan 15 11:53:54 2014 +0400
@@ -433,12 +433,11 @@
     if (isSWTInWebStart(env)) {
         forceEmbeddedMode = YES;
     }
-
     JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
-    jclass jc_SunToolkit = (*env)->FindClass(env, "sun/awt/SunToolkit");
-    jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_SunToolkit, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
-    jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_SunToolkit, sjm_getRootThreadGroup);
-    appkitThreadGroup = (*env)->NewGlobalRef(env, rootThreadGroup);
+    jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/misc/ThreadGroupUtils");
+    jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
+    jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup);
+    [ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)];
     // The current thread was attached in getJNIEnvUnchached.
     // Detach it back. It will be reattached later if needed with a proper TG
     [ThreadUtilities detachCurrentThread];
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.h	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.h	Wed Jan 15 11:53:54 2014 +0400
@@ -122,15 +122,13 @@
 #endif /* AWT_THREAD_ASSERTS */
 // --------------------------------------------------------------------------
 
-// Set from JNI_Onload
-extern jobject appkitThreadGroup;
-
 __attribute__((visibility("default")))
 @interface ThreadUtilities { }
 
 + (JNIEnv*)getJNIEnv;
 + (JNIEnv*)getJNIEnvUncached;
 + (void)detachCurrentThread;
++ (void)setAppkitThreadGroup:(jobject)group;
 
 //Wrappers for the corresponding JNFRunLoop methods with a check for main thread
 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.m	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.m	Wed Jan 15 11:53:54 2014 +0400
@@ -33,18 +33,18 @@
 // The following must be named "jvm", as there are extern references to it in AWT
 JavaVM *jvm = NULL;
 static JNIEnv *appKitEnv = NULL;
-jobject appkitThreadGroup = NULL;
+static jobject appkitThreadGroup = NULL;
 
 inline void attachCurrentThread(void** env) {
-    JavaVMAttachArgs args;
-    args.version = JNI_VERSION_1_2;
-    args.name = NULL; // Set from LWCToolkit
     if ([NSThread isMainThread]) {
+        JavaVMAttachArgs args;
+        args.version = JNI_VERSION_1_4;
+        args.name = "AppKit Thread";
         args.group = appkitThreadGroup;
+        (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
     } else {
-        args.group = NULL;
+        (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, NULL);
     }
-    (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args);
 }
 
 @implementation ThreadUtilities
@@ -67,6 +67,10 @@
     (*jvm)->DetachCurrentThread(jvm);
 }
 
++ (void)setAppkitThreadGroup:(jobject)group {
+    appkitThreadGroup = group;
+}
+
 + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
     if ([NSThread isMainThread] && wait == YES) {
         block(); 
--- a/src/share/classes/java/awt/EventQueue.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/java/awt/EventQueue.java	Wed Jan 15 11:53:54 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1061,11 +1061,11 @@
                             t.setContextClassLoader(classLoader);
                             t.setPriority(Thread.NORM_PRIORITY + 1);
                             t.setDaemon(false);
+                            AWTAutoShutdown.getInstance().notifyThreadBusy(t);
                             return t;
                         }
                     }
                 );
-                AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
                 dispatchThread.start();
             }
         } finally {
--- a/src/share/classes/sun/awt/AWTAutoShutdown.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/awt/AWTAutoShutdown.java	Wed Jan 15 11:53:54 2014 +0400
@@ -29,13 +29,13 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.Set;
 
 import sun.util.logging.PlatformLogger;
+import sun.misc.ThreadGroupUtils;
 
 /**
  * This class is to let AWT shutdown automatically when a user is done
@@ -217,7 +217,10 @@
         synchronized (activationLock) {
             synchronized (mainLock) {
                 if (!isReadyToShutdown() && blockerThread == null) {
-                    activateBlockerThread();
+                    AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                        activateBlockerThread();
+                        return null;
+                    });
                 } else {
                     mainLock.notifyAll();
                     timeoutPassed = false;
@@ -333,13 +336,12 @@
     /**
      * Creates and starts a new blocker thread. Doesn't return until
      * the new blocker thread starts.
+     *
+     * Must be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
      */
     private void activateBlockerThread() {
-        Thread thread = new Thread(SunToolkit.getRootThreadGroup(), this, "AWT-Shutdown");
-        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-            thread.setContextClassLoader(null);
-            return null;
-        });
+        Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown");
+        thread.setContextClassLoader(null);
         thread.setDaemon(false);
         blockerThread = thread;
         thread.start();
--- a/src/share/classes/sun/awt/SunToolkit.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/awt/SunToolkit.java	Wed Jan 15 11:53:54 2014 +0400
@@ -1186,17 +1186,6 @@
         return startupLocale;
     }
 
-    protected static ThreadGroup getRootThreadGroup() {
-        return AccessController.doPrivileged((PrivilegedAction<ThreadGroup>) () -> {
-            ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
-            ThreadGroup parentTG = currentTG.getParent();
-            while (parentTG != null) {
-                currentTG = parentTG;
-                parentTG = currentTG.getParent();
-            }
-            return currentTG;
-        });
-    }
     /**
      * Returns the default keyboard locale of the underlying operating system
      */
--- a/src/share/classes/sun/font/CreatedFontTracker.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/font/CreatedFontTracker.java	Wed Jan 15 11:53:54 2014 +0400
@@ -27,12 +27,15 @@
 
 import java.io.File;
 import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 import sun.awt.AppContext;
+import sun.misc.ThreadGroupUtils;
 
 public class CreatedFontTracker {
 
@@ -112,28 +115,18 @@
         static void init() {
             if (t == null) {
                 // Add a shutdown hook to remove the temp file.
-                java.security.AccessController.doPrivileged(
-                   new java.security.PrivilegedAction<Object>() {
-                      public Object run() {
-                          /* The thread must be a member of a thread group
-                           * which will not get GCed before VM exit.
-                           * Make its parent the top-level thread group.
-                           */
-                          ThreadGroup tg =
-                              Thread.currentThread().getThreadGroup();
-                          for (ThreadGroup tgn = tg;
-                               tgn != null;
-                               tg = tgn, tgn = tg.getParent());
-                          t = new Thread(tg, new Runnable() {
-                              public void run() {
-                                  runHooks();
-                              }
-                          });
-                          t.setContextClassLoader(null);
-                          Runtime.getRuntime().addShutdownHook(t);
-                          return null;
-                      }
-                   });
+                AccessController.doPrivileged(
+                        (PrivilegedAction<Void>) () -> {
+                            /* The thread must be a member of a thread group
+                             * which will not get GCed before VM exit.
+                             * Make its parent the top-level thread group.
+                             */
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            t = new Thread(rootTG, TempFileDeletionHook::runHooks);
+                            t.setContextClassLoader(null);
+                            Runtime.getRuntime().addShutdownHook(t);
+                            return null;
+                        });
             }
         }
 
--- a/src/share/classes/sun/font/SunFontManager.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/font/SunFontManager.java	Wed Jan 15 11:53:54 2014 +0400
@@ -52,6 +52,7 @@
 import sun.awt.AppContext;
 import sun.awt.FontConfiguration;
 import sun.awt.SunToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.java2d.FontSupport;
 import sun.util.logging.PlatformLogger;
 
@@ -2527,24 +2528,18 @@
                           });
                       }
                     };
-                    java.security.AccessController.doPrivileged(
-                       new java.security.PrivilegedAction<Object>() {
-                          public Object run() {
-                              /* The thread must be a member of a thread group
-                               * which will not get GCed before VM exit.
-                               * Make its parent the top-level thread group.
-                               */
-                              ThreadGroup tg =
-                                  Thread.currentThread().getThreadGroup();
-                              for (ThreadGroup tgn = tg;
-                                   tgn != null;
-                                   tg = tgn, tgn = tg.getParent());
-                              fileCloser = new Thread(tg, fileCloserRunnable);
-                              fileCloser.setContextClassLoader(null);
-                              Runtime.getRuntime().addShutdownHook(fileCloser);
-                              return null;
-                          }
-                    });
+                    AccessController.doPrivileged(
+                            (PrivilegedAction<Void>) () -> {
+                                /* The thread must be a member of a thread group
+                                 * which will not get GCed before VM exit.
+                                 * Make its parent the top-level thread group.
+                                 */
+                                ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                                fileCloser = new Thread(rootTG, fileCloserRunnable);
+                                fileCloser.setContextClassLoader(null);
+                                Runtime.getRuntime().addShutdownHook(fileCloser);
+                                return null;
+                            });
                 }
             }
         }
--- a/src/share/classes/sun/java2d/Disposer.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/java2d/Disposer.java	Wed Jan 15 11:53:54 2014 +0400
@@ -25,10 +25,14 @@
 
 package sun.java2d;
 
+import sun.misc.ThreadGroupUtils;
+
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Hashtable;
 
@@ -77,27 +81,21 @@
             }
         }
         disposerInstance = new Disposer();
-        java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<Object>() {
-                public Object run() {
-                    /* The thread must be a member of a thread group
-                     * which will not get GCed before VM exit.
-                     * Make its parent the top-level thread group.
-                     */
-                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                    for (ThreadGroup tgn = tg;
-                         tgn != null;
-                         tg = tgn, tgn = tg.getParent());
-                    Thread t =
-                        new Thread(tg, disposerInstance, "Java2D Disposer");
-                    t.setContextClassLoader(null);
-                    t.setDaemon(true);
-                    t.setPriority(Thread.MAX_PRIORITY);
-                    t.start();
-                    return null;
-                }
-            }
-        );
+        AccessController.doPrivileged(
+                (PrivilegedAction<Void>) () -> {
+                     /* The thread must be a member of a thread group
+                      * which will not get GCed before VM exit.
+                      * Make its parent the top-level thread group.
+                      */
+                     ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                     Thread t = new Thread(rootTG, disposerInstance, "Java2D Disposer");
+                     t.setContextClassLoader(null);
+                     t.setDaemon(true);
+                     t.setPriority(Thread.MAX_PRIORITY);
+                     t.start();
+                     return null;
+                 }
+         );
     }
 
     /**
--- a/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Wed Jan 15 11:53:54 2014 +0400
@@ -25,6 +25,7 @@
 
 package sun.java2d.opengl;
 
+import sun.misc.ThreadGroupUtils;
 import sun.java2d.pipe.RenderBuffer;
 import sun.java2d.pipe.RenderQueue;
 import static sun.java2d.pipe.BufferedOpCodes.*;
@@ -47,14 +48,8 @@
          * The thread must be a member of a thread group
          * which will not get GCed before VM exit.
          */
-        flusher = AccessController.doPrivileged(new PrivilegedAction<QueueFlusher>() {
-            public QueueFlusher run() {
-                ThreadGroup rootThreadGroup = Thread.currentThread().getThreadGroup();
-                while (rootThreadGroup.getParent() != null) {
-                    rootThreadGroup = rootThreadGroup.getParent();
-                }
-                return new QueueFlusher(rootThreadGroup);
-            }
+        flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) () -> {
+            return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup());
         });
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/misc/ThreadGroupUtils.java	Wed Jan 15 11:53:54 2014 +0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+/**
+ * A utility class needed to access the root {@code ThreadGroup}
+ *
+ * The class should not depend on any others, because it' called from JNI_OnLoad of the AWT
+ * native library. Triggering class loading could could lead to a deadlock.
+ */
+public final class ThreadGroupUtils {
+
+    private ThreadGroupUtils() {
+        // Avoid instantiation
+    }
+
+    /**
+     * Returns a root thread group.
+     * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
+     *
+     * @return a root {@code ThreadGroup}
+     */
+    public static ThreadGroup getRootThreadGroup() {
+        ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
+        ThreadGroup parentTG = currentTG.getParent();
+        while (parentTG != null) {
+            currentTG = parentTG;
+            parentTG = currentTG.getParent();
+        }
+        return currentTG;
+    }
+}
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Jan 15 11:53:54 2014 +0400
@@ -50,7 +50,8 @@
 import sun.awt.datatransfer.DataTransferer;
 import sun.font.FontConfigManager;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.misc.PerformanceLogger;
+import sun.misc.*;
+import sun.misc.ThreadGroupUtils;
 import sun.print.PrintJob2D;
 import sun.security.action.GetPropertyAction;
 import sun.security.action.GetBooleanAction;
@@ -254,27 +255,25 @@
         } finally {
             awtUnlock();
         }
-        PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
-            public Void run() {
-                Thread shutdownThread = new Thread(getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
-                        public void run() {
-                            XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
-                            if (peer != null) {
-                                peer.dispose();
-                            }
-                            if (xs != null) {
-                                ((XAWTXSettings)xs).dispose();
-                            }
-                            freeXKB();
-                            if (log.isLoggable(PlatformLogger.Level.FINE)) {
-                                dumpPeers();
-                            }
+        PrivilegedAction<Void> a = () -> {
+            Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
+                    public void run() {
+                        XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
+                        if (peer != null) {
+                            peer.dispose();
+                        }
+                        if (xs != null) {
+                            ((XAWTXSettings)xs).dispose();
                         }
-                    };
-                shutdownThread.setContextClassLoader(null);
-                Runtime.getRuntime().addShutdownHook(shutdownThread);
-                return null;
-            }
+                        freeXKB();
+                        if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                            dumpPeers();
+                        }
+                    }
+                };
+            shutdownThread.setContextClassLoader(null);
+            Runtime.getRuntime().addShutdownHook(shutdownThread);
+            return null;
         };
         AccessController.doPrivileged(a);
     }
@@ -316,16 +315,13 @@
             init();
             XWM.init();
 
-            PrivilegedAction<Thread> action = new PrivilegedAction() {
-                public Thread run() {
-                    Thread thread = new Thread(getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
-                    thread.setContextClassLoader(null);
-                    thread.setPriority(Thread.NORM_PRIORITY + 1);
-                    thread.setDaemon(true);
-                    return thread;
-                }
-            };
-            toolkitThread = AccessController.doPrivileged(action);
+            toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
+                Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
+                thread.setContextClassLoader(null);
+                thread.setPriority(Thread.NORM_PRIORITY + 1);
+                thread.setDaemon(true);
+                return thread;
+            });
             toolkitThread.start();
         }
     }
--- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Wed Jan 15 11:53:54 2014 +0400
@@ -42,6 +42,8 @@
 import sun.java2d.xr.XRGraphicsConfig;
 import sun.java2d.loops.SurfaceType;
 
+import sun.misc.ThreadGroupUtils;
+
 /**
  * This is an implementation of a GraphicsDevice object for a single
  * X11 screen.
@@ -423,28 +425,19 @@
             // is already in the original DisplayMode at that time, this
             // hook will have no effect)
             shutdownHookRegistered = true;
-            PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
-                public Void run() {
-                    ThreadGroup mainTG = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = mainTG.getParent();
-                    while (parentTG != null) {
-                        mainTG = parentTG;
-                        parentTG = mainTG.getParent();
+            PrivilegedAction<Void> a = () -> {
+                ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                Runnable r = () -> {
+                    Window old = getFullScreenWindow();
+                    if (old != null) {
+                        exitFullScreenExclusive(old);
+                        setDisplayMode(origDisplayMode);
                     }
-                    Runnable r = new Runnable() {
-                            public void run() {
-                                Window old = getFullScreenWindow();
-                                if (old != null) {
-                                    exitFullScreenExclusive(old);
-                                    setDisplayMode(origDisplayMode);
-                                }
-                            }
-                        };
-                    Thread t = new Thread(mainTG, r,"Display-Change-Shutdown-Thread-"+screen);
-                    t.setContextClassLoader(null);
-                    Runtime.getRuntime().addShutdownHook(t);
-                    return null;
-                }
+                };
+                Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen);
+                t.setContextClassLoader(null);
+                Runtime.getRuntime().addShutdownHook(t);
+                return null;
             };
             AccessController.doPrivileged(a);
         }
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jan 15 11:53:54 2014 +0400
@@ -39,6 +39,7 @@
 
 import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
+import sun.misc.ThreadGroupUtils;
 
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
@@ -503,23 +504,16 @@
                     }
                 }
             };
-            comThread =
-                AccessController.doPrivileged(
-                    new PrivilegedAction<Thread>() {
-                        public Thread run() {
+            comThread =  AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
                             /* The thread must be a member of a thread group
                              * which will not get GCed before VM exit.
                              * Make its parent the top-level thread group.
                              */
-                            ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                            for (ThreadGroup tgn = tg;
-                                 tgn != null;
-                                 tg = tgn, tgn = tg.getParent());
-                            Thread thread = new Thread(tg, comRun, "Swing-Shell");
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            Thread thread = new Thread(rootTG, comRun, "Swing-Shell");
                             thread.setDaemon(true);
                             return thread;
                         }
-                    }
                 );
             return comThread;
         }
--- a/src/windows/classes/sun/awt/windows/WToolkit.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java	Wed Jan 15 11:53:54 2014 +0400
@@ -40,6 +40,7 @@
 import sun.awt.AWTPermissions;
 import sun.awt.LightweightFrame;
 import sun.awt.SunToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.awt.Win32GraphicsDevice;
 import sun.awt.Win32GraphicsEnvironment;
 import sun.awt.datatransfer.DataTransferer;
@@ -242,7 +243,8 @@
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
         // Find a root TG and attach Appkit thread to it
-        ThreadGroup rootTG = getRootThreadGroup();
+        ThreadGroup rootTG = AccessController.doPrivileged(
+                (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
         if (!startToolkitThread(this, rootTG)) {
             Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows");
             toolkitThread.setDaemon(true);
@@ -270,20 +272,12 @@
     }
 
     private final void registerShutdownHook() {
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            @Override
-            public Void run() {
-                Thread shutdown = new Thread(getRootThreadGroup(), new Runnable() {
-                    @Override
-                    public void run() {
-                        shutdown();
-                    }
-                });
-                shutdown.setContextClassLoader(null);
-                Runtime.getRuntime().addShutdownHook(shutdown);
-                return null;
-            }
-        });
+        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+            Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
+            shutdown.setContextClassLoader(null);
+            Runtime.getRuntime().addShutdownHook(shutdown);
+            return null;
+         });
      }
 
     @Override
--- a/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Thu Jan 16 17:49:40 2014 +0100
+++ b/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Wed Jan 15 11:53:54 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,8 +36,9 @@
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.HashMap;
-import sun.awt.SunToolkit;
+
 import sun.awt.AWTAccessor;
+import sun.misc.ThreadGroupUtils;
 import sun.awt.Win32GraphicsConfig;
 import sun.awt.windows.WComponentPeer;
 import sun.java2d.InvalidPipeException;
@@ -92,21 +93,12 @@
     public D3DScreenUpdateManager() {
         done = false;
         AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
-                    ThreadGroup currentTG =
-                        Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = currentTG.getParent();
-                    while (parentTG != null) {
-                        currentTG = parentTG;
-                        parentTG = currentTG.getParent();
-                    }
-                    Thread shutdown = new Thread(currentTG, new Runnable() {
-                            public void run() {
-                                done = true;
-                                wakeUpUpdateThread();
-                            }
-                        });
+                (PrivilegedAction<Void>) () -> {
+                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                    Thread shutdown = new Thread(rootTG, () -> {
+                        done = true;
+                        wakeUpUpdateThread();
+                    });
                     shutdown.setContextClassLoader(null);
                     try {
                         Runtime.getRuntime().addShutdownHook(shutdown);
@@ -115,7 +107,6 @@
                     }
                     return null;
                 }
-            }
         );
     }
 
@@ -354,21 +345,17 @@
      */
     private synchronized void startUpdateThread() {
         if (screenUpdater == null) {
-            screenUpdater = (Thread)java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                    public Object run() {
-                        ThreadGroup tg =
-                            Thread.currentThread().getThreadGroup();
-                        for (ThreadGroup tgn = tg;
-                             tgn != null; tg = tgn, tgn = tg.getParent());
-                        Thread t = new Thread(tg, D3DScreenUpdateManager.this,
-                                              "D3D Screen Updater");
+            screenUpdater = AccessController.doPrivileged(
+                    (PrivilegedAction<Thread>) () -> {
+                        ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                        Thread t = new Thread(rootTG,
+                                D3DScreenUpdateManager.this,
+                                "D3D Screen Updater");
                         // REMIND: should it be higher?
                         t.setPriority(Thread.NORM_PRIORITY + 2);
                         t.setDaemon(true);
                         return t;
-                    }
-            });
+                    });
             screenUpdater.start();
         } else {
             wakeUpUpdateThread();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Toolkit/LoadAWTCrashTest/LoadAWTCrashTest.java	Wed Jan 15 11:53:54 2014 +0400
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+  @test
+  @bug 8031477
+  @summary Crash while awt starting
+  @author Petr Pchelko
+  @run main/othervm LoadAWTCrashTest
+*/
+
+public class LoadAWTCrashTest {
+    public static void main(String[] args) {
+        System.loadLibrary("awt");
+        // If the bug is present JVM would crash or deadlock
+    }
+}