changeset 7032:6d918cec0812

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:42:50 +0400
parents 42e68c7fbe98
children 473208bb112f
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, 280 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/font/CFontManager.java	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/macosx/classes/sun/font/CFontManager.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -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,22 @@
                                 });
                     }
                 };
-                java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedAction<Object>() {
-                            public Object run() {
+                AccessController.doPrivileged(
+                        new PrivilegedAction<Void>() {
+                            @Override
+                            public Void 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);
+                                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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -37,6 +37,7 @@
 
 import sun.awt.*;
 import sun.lwawt.macosx.*;
+import sun.misc.ThreadGroupUtils;
 import sun.print.*;
 
 public abstract class LWToolkit extends SunToolkit implements Runnable {
@@ -66,22 +67,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();
+        ThreadGroup rootTG = AccessController.doPrivileged(
+                new PrivilegedAction<ThreadGroup>() {
+                    @Override
+                    public ThreadGroup run() {
+                        return ThreadGroupUtils.getRootThreadGroup();
                     }
-                    return currentTG;
-                }
-            }
-        );
+                });
 
         Runtime.getRuntime().addShutdownHook(
-            new Thread(mainTG, new Runnable() {
+            new Thread(rootTG, new Runnable() {
+                @Override
                 public void run() {
                     shutdown();
                     waitForRunState(STATE_CLEANUP);
@@ -89,7 +85,7 @@
             })
         );
 
-        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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/macosx/native/sun/awt/awt.m	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -433,10 +433,11 @@
     }
 
     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 getJNIEnvUncached.
     // Detach it back. It will be reattached later if needed with a proper TG
     [ThreadUtilities detachCurrentThread];
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.h	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.h	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.m	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/java/awt/EventQueue.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, 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
@@ -1043,11 +1043,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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/awt/AWTAutoShutdown.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -28,10 +28,11 @@
 import java.awt.AWTEvent;
 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 sun.misc.ThreadGroupUtils;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -214,7 +215,13 @@
         synchronized (activationLock) {
             synchronized (mainLock) {
                 if (!isReadyToShutdown() && blockerThread == null) {
-                    activateBlockerThread();
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                        @Override
+                        public Void run() {
+                            activateBlockerThread();
+                            return null;
+                        }
+                    });
                 } else {
                     mainLock.notifyAll();
                     timeoutPassed = false;
@@ -328,16 +335,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() {
-        final Thread thread = new Thread(SunToolkit.getRootThreadGroup(), this, "AWT-Shutdown");
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            @Override
-            public Void run() {
-                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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/awt/SunToolkit.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1127,20 +1127,6 @@
         return startupLocale;
     }
 
-    protected static ThreadGroup getRootThreadGroup() {
-        return AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
-            @Override
-            public ThreadGroup run() {
-                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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/font/CreatedFontTracker.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -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,25 @@
         static void init() {
             if (t == null) {
                 // Add a shutdown hook to remove the temp file.
-                java.security.AccessController.doPrivileged(
-                   new java.security.PrivilegedAction() {
-                      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(new PrivilegedAction<Void>() {
+                            @Override
+                            public Void 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 rootTG = ThreadGroupUtils.getRootThreadGroup();
+                                t = new Thread(rootTG, new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        runHooks();
+                                    }
+                                });
+                                t.setContextClassLoader(null);
+                                Runtime.getRuntime().addShutdownHook(t);
+                                return null;
+                            }
+                        });
             }
         }
 
--- a/src/share/classes/sun/font/SunFontManager.java	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/font/SunFontManager.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -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;
 
@@ -2521,24 +2522,20 @@
                           });
                       }
                     };
-                    java.security.AccessController.doPrivileged(
-                       new java.security.PrivilegedAction() {
-                          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(new PrivilegedAction<Void>() {
+                                @Override
+                                public Void 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 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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/java2d/Disposer.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -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;
 
@@ -71,26 +75,22 @@
             }
         }
         disposerInstance = new Disposer();
-        java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override
+                    public Void 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;
+                        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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -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.*;
@@ -48,12 +49,9 @@
          * which will not get GCed before VM exit.
          */
         flusher = AccessController.doPrivileged(new PrivilegedAction<QueueFlusher>() {
+            @Override
             public QueueFlusher run() {
-                ThreadGroup rootThreadGroup = Thread.currentThread().getThreadGroup();
-                while (rootThreadGroup.getParent() != null) {
-                    rootThreadGroup = rootThreadGroup.getParent();
-                }
-                return new QueueFlusher(rootThreadGroup);
+                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:42:50 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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -49,6 +49,7 @@
 import sun.awt.*;
 import sun.font.FontConfigManager;
 import sun.misc.PerformanceLogger;
+import sun.misc.ThreadGroupUtils;
 import sun.print.PrintJob2D;
 import sun.security.action.GetPropertyAction;
 import sun.security.action.GetBooleanAction;
@@ -311,7 +312,7 @@
         }
         PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
             public Void run() {
-                Thread shutdownThread = new Thread(getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
+                Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") {
                         public void run() {
                             XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
                             if (peer != null) {
@@ -373,17 +374,16 @@
             init();
             XWM.init();
             SunToolkit.setDataTransfererClassName(DATA_TRANSFERER_CLASS_NAME);
-
-            PrivilegedAction<Thread> action = new PrivilegedAction() {
+            toolkitThread = AccessController.doPrivileged(new PrivilegedAction<Thread>() {
+                @Override
                 public Thread run() {
-                    Thread thread = new Thread(getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
+                    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 = AccessController.doPrivileged(action);
+            });
             toolkitThread.start();
         }
     }
--- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -41,6 +41,7 @@
 import sun.java2d.opengl.GLXGraphicsConfig;
 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
@@ -424,23 +425,20 @@
             // hook will have no effect)
             shutdownHookRegistered = true;
             PrivilegedAction<Void> a = new PrivilegedAction<Void>() {
+                @Override
                 public Void run() {
-                    ThreadGroup mainTG = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parentTG = mainTG.getParent();
-                    while (parentTG != null) {
-                        mainTG = parentTG;
-                        parentTG = mainTG.getParent();
-                    }
+                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
                     Runnable r = new Runnable() {
-                            public void run() {
-                                Window old = getFullScreenWindow();
-                                if (old != null) {
-                                    exitFullScreenExclusive(old);
-                                    setDisplayMode(origDisplayMode);
-                                }
+                        @Override
+                        public void run() {
+                            Window old = getFullScreenWindow();
+                            if (old != null) {
+                                exitFullScreenExclusive(old);
+                                setDisplayMode(origDisplayMode);
                             }
-                        };
-                    Thread t = new Thread(mainTG, r,"Display-Change-Shutdown-Thread-"+screen);
+                        }
+                    };
+                    Thread t = new Thread(rootTG, r, "Display-Change-Shutdown-Thread-" + screen);
                     t.setContextClassLoader(null);
                     Runtime.getRuntime().addShutdownHook(t);
                     return null;
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -41,6 +41,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.
@@ -505,23 +506,19 @@
                     }
                 }
             };
-            comThread =
-                AccessController.doPrivileged(
-                    new PrivilegedAction<Thread>() {
-                        public Thread run() {
+            comThread =  AccessController.doPrivileged(new PrivilegedAction<Thread>() {
+                @Override
+                public Thread 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 thread = new Thread(tg, comRun, "Swing-Shell");
-                            thread.setDaemon(true);
-                            return thread;
-                        }
-                    }
+                    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	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java	Wed Jan 15 11:42:50 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, 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
@@ -38,6 +38,7 @@
 import java.security.PrivilegedAction;
 import sun.awt.AWTAutoShutdown;
 import sun.awt.SunToolkit;
+import sun.misc.ThreadGroupUtils;
 import sun.awt.Win32GraphicsDevice;
 import sun.awt.Win32GraphicsEnvironment;
 import sun.java2d.d3d.D3DRenderQueue;
@@ -233,7 +234,12 @@
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
         // Find a root TG and attach Appkit thread to it
-        ThreadGroup rootTG = getRootThreadGroup();
+        ThreadGroup rootTG = AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
+                    @Override
+                    public ThreadGroup run() {
+                        return ThreadGroupUtils.getRootThreadGroup();
+                    }
+                });
         if (!startToolkitThread(this, rootTG)) {
             Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows");
             toolkitThread.setDaemon(true);
@@ -265,7 +271,7 @@
     private final void registerShutdownHook() {
         AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
-                Thread shutdown = new Thread(getRootThreadGroup(), new Runnable() {
+                Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), new Runnable() {
                     public void run() {
                         shutdown();
                     }
--- a/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Wed Jan 15 11:23:07 2014 +0800
+++ b/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Wed Jan 15 11:42:50 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,30 +93,26 @@
     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() {
+                new PrivilegedAction<Void>() {
+                    @Override
+                    public Void run() {
+                        ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                        Thread shutdown = new Thread(rootTG, new Runnable() {
+                            @Override
                             public void run() {
                                 done = true;
                                 wakeUpUpdateThread();
                             }
                         });
-                    shutdown.setContextClassLoader(null);
-                    try {
-                        Runtime.getRuntime().addShutdownHook(shutdown);
-                    } catch (Exception e) {
-                        done = true;
+                        shutdown.setContextClassLoader(null);
+                        try {
+                            Runtime.getRuntime().addShutdownHook(shutdown);
+                        } catch (Exception e) {
+                            done = true;
+                        }
+                        return null;
                     }
-                    return null;
                 }
-            }
         );
     }
 
@@ -354,21 +351,20 @@
      */
     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");
-                        // REMIND: should it be higher?
-                        t.setPriority(Thread.NORM_PRIORITY + 2);
-                        t.setDaemon(true);
-                        return t;
-                    }
-            });
+            screenUpdater = AccessController.doPrivileged(
+                    new PrivilegedAction<Thread>() {
+                        @Override
+                        public Thread run() {
+                            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:42:50 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
+    }
+}