8027771: Enhance thread contexts
authorserb
Fri, 03 Apr 2015 17:17:36 +0300
changeset 29922 7b9c1e1532cf
parent 29921 f13586cdb0e4
child 29923 e3ee0996bedb
8027771: Enhance thread contexts Reviewed-by: anthony, serb
jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java
jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java
jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java
jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java
jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java
jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java
jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java
jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java
jdk/src/java.desktop/share/classes/javax/swing/JTable.java
jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java
jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java
jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java
jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java
jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java
jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java
jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java
jdk/src/java.desktop/share/classes/sun/awt/AppContext.java
jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java
jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java
jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java
jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java
jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java
jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java
jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java
jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java
jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java
jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java
jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java
jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java
jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java
jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java
jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java
jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,15 +25,16 @@
 
 package com.apple.laf;
 
+
 import java.beans.*;
 import java.io.File;
 import java.util.*;
-
 import javax.swing.*;
 import javax.swing.event.ListDataEvent;
 import javax.swing.filechooser.FileSystemView;
 import javax.swing.table.AbstractTableModel;
 
+import sun.misc.ManagedLocalsThread;
 /**
  * NavServices-like implementation of a file Table
  *
@@ -42,7 +43,7 @@
 @SuppressWarnings("serial") // Superclass is not serializable across versions
 class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeListener {
     private final JTable fFileList;
-    private LoadFilesThread loadThread = null;
+    private FilesLoader filesLoader = null;
     private Vector<File> files = null;
 
     JFileChooser filechooser = null;
@@ -141,9 +142,9 @@
 
     public void runWhenDone(final Runnable runnable){
          synchronized (fileCacheLock) {
-             if (loadThread != null) {
-                 if (loadThread.isAlive()) {
-                     loadThread.queuedTasks.add(runnable);
+             if (filesLoader != null) {
+                 if (filesLoader.loadThread.isAlive()) {
+                     filesLoader.queuedTasks.add(runnable);
                      return;
                  }
              }
@@ -160,9 +161,9 @@
             return;
         }
 
-        if (loadThread != null) {
+        if (filesLoader != null) {
             // interrupt
-            loadThread.interrupt();
+            filesLoader.loadThread.interrupt();
         }
 
         fetchID++;
@@ -173,8 +174,7 @@
             fileCache = new Vector<SortableFile>(50);
         }
 
-        loadThread = new LoadFilesThread(currentDirectory, fetchID);
-        loadThread.start();
+        filesLoader = new FilesLoader(currentDirectory, fetchID);
     }
 
     public int getColumnCount() {
@@ -373,17 +373,25 @@
         }
     }
 
-    class LoadFilesThread extends Thread {
-        Vector<Runnable> queuedTasks = new Vector<Runnable>();
+    class FilesLoader implements Runnable {
+        Vector<Runnable> queuedTasks = new Vector<>();
         File currentDirectory = null;
         int fid;
+        Thread loadThread;
 
-        public LoadFilesThread(final File currentDirectory, final int fid) {
-            super("Aqua L&F File Loading Thread");
+        public FilesLoader(final File currentDirectory, final int fid) {
             this.currentDirectory = currentDirectory;
             this.fid = fid;
+            String name = "Aqua L&F File Loading Thread";
+            if (System.getSecurityManager() == null) {
+                this.loadThread = new Thread(FilesLoader.this, name);
+            } else {
+                this.loadThread = new ManagedLocalsThread(FilesLoader.this, name);
+            }
+            this.loadThread.start();
         }
 
+        @Override
         public void run() {
             final Vector<DoChangeContents> runnables = new Vector<DoChangeContents>(10);
             final FileSystemView fileSystem = filechooser.getFileSystemView();
@@ -415,7 +423,7 @@
                 runnables.addElement(runnable);
                 SwingUtilities.invokeLater(runnable);
                 chunk = new Vector<SortableFile>(10);
-                if (isInterrupted()) {
+                if (loadThread.isInterrupted()) {
                     // interrupted, cancel all runnables
                     cancelRunnables(runnables);
                     return;
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Fri Apr 03 17:17:36 2015 +0300
@@ -42,6 +42,7 @@
 import sun.awt.HeadlessToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.lwawt.macosx.*;
+import sun.misc.InnocuousThread;
 
 public final class CFontManager extends SunFontManager {
     private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
@@ -211,14 +212,18 @@
                                 });
                     }
                 };
-                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);
+                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                            if (System.getSecurityManager() == null) {
+                                /* 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);
+                            } else {
+                                /* InnocuousThread is a member of a correct TG by default */
+                                fileCloser = new InnocuousThread(fileCloserRunnable);
+                            }
                             fileCloser.setContextClassLoader(null);
                             Runtime.getRuntime().addShutdownHook(fileCloser);
                             return null;
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Fri Apr 03 17:17:36 2015 +0300
@@ -35,6 +35,7 @@
 import java.util.*;
 
 import sun.awt.*;
+import sun.misc.InnocuousThread;
 import sun.print.*;
 import sun.awt.util.ThreadGroupUtils;
 
@@ -71,22 +72,32 @@
      */
     protected final void init() {
         AWTAutoShutdown.notifyToolkitThreadBusy();
-
-        ThreadGroup rootTG = AccessController.doPrivileged(
-                (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
-
-        Runtime.getRuntime().addShutdownHook(
-            new Thread(rootTG, () -> {
+        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+            Runnable shutdownRunnable = () -> {
                 shutdown();
                 waitForRunState(STATE_CLEANUP);
-            })
-        );
+            };
+            Thread shutdown;
+            if (System.getSecurityManager() == null) {
+                shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            } else {
+                shutdown = new InnocuousThread(shutdownRunnable);
+            }
+            shutdown.setContextClassLoader(null);
+            Runtime.getRuntime().addShutdownHook(shutdown);
 
-        Thread toolkitThread = new Thread(rootTG, this, "AWT-LW");
-        toolkitThread.setDaemon(true);
-        toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
-        toolkitThread.start();
-
+            String name = "AWT-LW";
+            Thread toolkitThread;
+            if (System.getSecurityManager() == null) {
+                toolkitThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), LWToolkit.this, name);
+            } else {
+                toolkitThread = new InnocuousThread(LWToolkit.this, name);
+            }
+            toolkitThread.setDaemon(true);
+            toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
+            toolkitThread.start();
+            return null;
+        });
         waitForRunState(STATE_MESSAGELOOP);
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -31,7 +31,6 @@
 import java.awt.dnd.*;
 import java.awt.event.*;
 import java.awt.image.*;
-import java.awt.peer.*;
 
 import javax.swing.*;
 import javax.swing.text.*;
@@ -44,6 +43,7 @@
 import sun.lwawt.LWComponentPeer;
 import sun.lwawt.LWWindowPeer;
 import sun.lwawt.PlatformWindow;
+import sun.misc.ManagedLocalsThread;
 
 
 public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@@ -164,28 +164,29 @@
         // are posted during dragging by native event handlers.
 
         try {
-            Thread dragThread = new Thread() {
-                public void run() {
-                    final long nativeDragSource = getNativeContext();
-                    try {
-                        doDragging(nativeDragSource);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    } finally {
-                        releaseNativeDragSource(nativeDragSource);
-                        fDragImage = null;
-                        if (fDragCImage != null) {
-                            fDragCImage.dispose();
-                            fDragCImage = null;
-                        }
+            Runnable dragRunnable = () -> {
+                final long nativeDragSource = getNativeContext();
+                try {
+                    doDragging(nativeDragSource);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    releaseNativeDragSource(nativeDragSource);
+                    fDragImage = null;
+                    if (fDragCImage != null) {
+                        fDragCImage.dispose();
+                        fDragCImage = null;
                     }
                 }
             };
-
+            Thread dragThread;
+            if (System.getSecurityManager() == null) {
+                dragThread = new Thread(dragRunnable);
+            } else {
+                dragThread = new ManagedLocalsThread(dragRunnable);
+            }
             dragThread.start();
-        }
-
-        catch (Exception e) {
+        } catch (Exception e) {
             final long nativeDragSource = getNativeContext();
             setNativeContext(0);
             releaseNativeDragSource(nativeDragSource);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Fri Apr 03 17:17:36 2015 +0300
@@ -37,6 +37,7 @@
 import sun.awt.CausedFocusEvent.Cause;
 import sun.awt.AWTAccessor;
 import sun.java2d.pipe.Region;
+import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetBooleanAction;
 
 class CFileDialog implements FileDialogPeer {
@@ -119,7 +120,11 @@
         if (visible) {
             // Java2 Dialog class requires peer to run code in a separate thread
             // and handles keeping the call modal
-            new Thread(new Task()).start(); // invokes my 'run' method, below...
+            if (System.getSecurityManager() == null) {
+                new Thread(new Task()).start();
+            } else {
+                new ManagedLocalsThread(new Task()).start();
+            }
         }
         // We hide ourself before "show" returns - setVisible(false)
         // doesn't apply
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -29,6 +29,7 @@
 import java.awt.dnd.*;
 
 import sun.lwawt.*;
+import sun.misc.ManagedLocalsThread;
 
 public class CPrinterDialogPeer extends LWWindowPeer {
     static {
@@ -53,13 +54,16 @@
 
     public void setVisible(boolean visible) {
         if (visible) {
-            new Thread(new Runnable() {
-                public void run() {
-                    CPrinterDialog printerDialog = (CPrinterDialog)fTarget;
-                    printerDialog.setRetVal(printerDialog.showDialog());
-                    printerDialog.setVisible(false);
-                }
-            }).start();
+            Runnable task = () -> {
+                CPrinterDialog printerDialog = (CPrinterDialog)fTarget;
+                printerDialog.setRetVal(printerDialog.showDialog());
+                printerDialog.setVisible(false);
+            };
+            if (System.getSecurityManager() == null) {
+                new Thread(task).start();
+            } else {
+                new ManagedLocalsThread(task).start();
+            }
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Fri Apr 03 17:17:36 2015 +0300
@@ -39,6 +39,7 @@
 import javax.print.attribute.standard.PageRanges;
 
 import sun.java2d.*;
+import sun.misc.ManagedLocalsThread;
 import sun.print.*;
 
 public final class CPrinterJob extends RasterPrinterJob {
@@ -731,9 +732,12 @@
 
     // upcall from native
     private static void detachPrintLoop(final long target, final long arg) {
-        new Thread() { public void run() {
-            _safePrintLoop(target, arg);
-        }}.start();
+        Runnable task = () -> _safePrintLoop(target, arg);
+        if (System.getSecurityManager() == null) {
+            new Thread(task).start();
+        } else {
+            new ManagedLocalsThread(task).start();
+        }
     }
     private static native void _safePrintLoop(long target, long arg);
 
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,7 +25,12 @@
 
 package com.sun.imageio.stream;
 
+import sun.awt.util.ThreadGroupUtils;
+import sun.misc.InnocuousThread;
+
 import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Set;
 import java.util.WeakHashMap;
 import javax.imageio.stream.ImageInputStream;
@@ -81,27 +86,25 @@
                     }
                 };
 
-                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());
-                            streamCloser = new Thread(tg, streamCloserRunnable);
-                            /* Set context class loader to null in order to avoid
-                             * keeping a strong reference to an application classloader.
-                             */
-                            streamCloser.setContextClassLoader(null);
-                            Runtime.getRuntime().addShutdownHook(streamCloser);
-                            return null;
-                        }
-                    });
+                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+                    if (System.getSecurityManager() == null) {
+                        /* 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 = ThreadGroupUtils.getRootThreadGroup();
+                        streamCloser = new Thread(tg, streamCloserRunnable);
+                    } else {
+                        /* InnocuousThread is a member of a correct TG by default */
+                        streamCloser = new InnocuousThread(streamCloserRunnable);
+                    }
+                    /* Set context class loader to null in order to avoid
+                     * keeping a strong reference to an application classloader.
+                     */
+                    streamCloser.setContextClassLoader(null);
+                    Runtime.getRuntime().addShutdownHook(streamCloser);
+                    return null;
+                });
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Fri Apr 03 17:17:36 2015 +0300
@@ -64,6 +64,7 @@
 import sun.awt.OSInfo;
 import sun.awt.shell.ShellFolder;
 import sun.font.FontUtilities;
+import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetPropertyAction;
 
 import sun.swing.DefaultLayoutStyle;
@@ -2037,7 +2038,11 @@
             if (audioRunnable != null) {
                 // Runnable appears to block until completed playing, hence
                 // start up another thread to handle playing.
-                new Thread(audioRunnable).start();
+                if (System.getSecurityManager() == null) {
+                    new Thread(audioRunnable).start();
+                } else {
+                    new ManagedLocalsThread(audioRunnable).start();
+                }
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,9 @@
 
 package com.sun.media.sound;
 
+import sun.misc.InnocuousThread;
+import sun.misc.ManagedLocalsThread;
+
 import java.io.BufferedInputStream;
 import java.io.InputStream;
 import java.io.File;
@@ -144,7 +147,13 @@
                                final String threadName,
                                final boolean isDaemon, final int priority,
                                final boolean doStart) {
-        Thread thread = new Thread(runnable);
+        Thread thread;
+        if (System.getSecurityManager() == null) {
+            thread = new Thread(runnable);
+        } else {
+            thread = new ManagedLocalsThread(runnable);
+        }
+
         if (threadName != null) {
             thread.setName(threadName);
         }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Fri Apr 03 17:17:36 2015 +0300
@@ -24,6 +24,8 @@
  */
 package com.sun.media.sound;
 
+import sun.misc.ManagedLocalsThread;
+
 import java.io.IOException;
 
 import javax.sound.sampled.AudioInputStream;
@@ -53,7 +55,11 @@
         if (active)
             return;
         active = true;
-        audiothread = new Thread(this);
+        if (System.getSecurityManager() == null) {
+            audiothread = new Thread(this);
+        } else {
+            audiothread = new ManagedLocalsThread(this);
+        }
         audiothread.setDaemon(true);
         audiothread.setPriority(Thread.MAX_PRIORITY);
         audiothread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Fri Apr 03 17:17:36 2015 +0300
@@ -24,13 +24,14 @@
  */
 package com.sun.media.sound;
 
+import sun.misc.ManagedLocalsThread;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-
 /**
  * A jitter corrector to be used with SoftAudioPusher.
  *
@@ -215,7 +216,11 @@
                 }
             };
 
-            thread = new Thread(runnable);
+            if (System.getSecurityManager() == null) {
+                thread = new Thread(runnable);
+            } else {
+                thread = new ManagedLocalsThread(runnable);
+            }
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,8 @@
 
 package com.sun.media.sound;
 
+import sun.misc.ManagedLocalsThread;
+
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -139,7 +141,11 @@
                      pusher = null;
                      jitter_stream = null;
                      sourceDataLine = null;
-                     new Thread(runnable).start();
+                     if (System.getSecurityManager() == null) {
+                        new Thread(runnable).start();
+                     } else {
+                         new ManagedLocalsThread(runnable).start();
+                     }
                  }
                  return len;
              }
--- a/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Fri Apr 03 17:17:36 2015 +0300
@@ -30,6 +30,8 @@
 import java.awt.event.WindowEvent;
 
 import java.util.ArrayList;
+
+import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 import sun.awt.dnd.SunDragSourceContextPeer;
@@ -53,7 +55,7 @@
  *
  * @since 1.1
  */
-class EventDispatchThread extends Thread {
+class EventDispatchThread extends ManagedLocalsThread {
 
     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
 
@@ -65,7 +67,7 @@
     private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
 
     EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
-        super(group, name);
+        super(group, null, name);
         setEventQueue(queue);
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -34,10 +34,11 @@
  **********************************************************************/
 
 package java.awt.image.renderable;
-import java.awt.color.ColorSpace;
+
+import sun.misc.ManagedLocalsThread;
+
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
-import java.awt.image.DirectColorModel;
 import java.awt.image.ImageConsumer;
 import java.awt.image.ImageProducer;
 import java.awt.image.Raster;
@@ -135,7 +136,13 @@
     public synchronized void startProduction(ImageConsumer ic) {
         addConsumer(ic);
         // Need to build a runnable object for the Thread.
-        Thread thread = new Thread(this, "RenderableImageProducer Thread");
+        String name = "RenderableImageProducer Thread";
+        Thread thread;
+        if (System.getSecurityManager() == null) {
+            thread = new Thread(this, name);
+        } else {
+            thread = new ManagedLocalsThread(this);
+        }
         thread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Fri Apr 03 17:17:36 2015 +0300
@@ -53,6 +53,8 @@
 
 import javax.print.attribute.*;
 import javax.print.PrintService;
+
+import sun.misc.ManagedLocalsThread;
 import sun.reflect.misc.ReflectUtil;
 
 import sun.swing.SwingUtilities2;
@@ -6384,25 +6386,28 @@
 
         // this runnable will be used to do the printing
         // (and save any throwables) on another thread
-        Runnable runnable = new Runnable() {
-            public void run() {
-                try {
-                    // do the printing
-                    job.print(copyAttr);
-                } catch (Throwable t) {
-                    // save any Throwable to be rethrown
-                    synchronized(lock) {
-                        printError = t;
-                    }
-                } finally {
-                    // we're finished - hide the dialog
-                    printingStatus.dispose();
-                }
+        Runnable runnable = () -> {
+            try {
+                // do the printing
+                job.print(copyAttr);
+            } catch (Throwable t) {
+                // save any Throwable to be rethrown
+                synchronized(lock) {
+                    printError = t;
+                }
+            } finally {
+                // we're finished - hide the dialog
+                printingStatus.dispose();
             }
         };
 
         // start printing on another thread
-        Thread th = new Thread(runnable);
+        Thread th;
+        if  (System.getSecurityManager() == null) {
+            th = new Thread(runnable);
+        } else {
+            th = new ManagedLocalsThread(runnable);
+        }
         th.start();
 
         printingStatus.showModal(true);
--- a/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Fri Apr 03 17:17:36 2015 +0300
@@ -29,12 +29,14 @@
 
 
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 import java.util.concurrent.atomic.AtomicLong;
 import sun.awt.AppContext;
-
+import sun.misc.InnocuousThread;
 
 
 /**
@@ -94,18 +96,19 @@
         if (! running) {
             runningLock.lock();
             try {
-                final ThreadGroup threadGroup =
-                    AppContext.getAppContext().getThreadGroup();
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction<Object>() {
-                    public Object run() {
-                        Thread timerThread = new Thread(threadGroup, TimerQueue.this,
-                                                        "TimerQueue");
-                        timerThread.setDaemon(true);
-                        timerThread.setPriority(Thread.NORM_PRIORITY);
-                        timerThread.start();
-                        return null;
+                final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup();
+                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+                    String name = "TimerQueue";
+                    Thread timerThread;
+                    if (System.getSecurityManager() == null) {
+                        timerThread = new Thread(threadGroup, TimerQueue.this, name);
+                    } else {
+                        timerThread = new InnocuousThread(threadGroup, TimerQueue.this, name);
                     }
+                    timerThread.setDaemon(true);
+                    timerThread.setPriority(Thread.NORM_PRIORITY);
+                    timerThread.start();
+                    return null;
                 });
                 running = true;
             } finally {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,15 +25,19 @@
 
 package javax.swing.plaf.basic;
 
-import java.io.File;
-import java.util.*;
-import java.util.concurrent.Callable;
+import sun.awt.shell.ShellFolder;
+import sun.misc.ManagedLocalsThread;
+
 import javax.swing.*;
-import javax.swing.filechooser.*;
-import javax.swing.event.*;
-import java.beans.*;
-
-import sun.awt.shell.ShellFolder;
+import javax.swing.event.ListDataEvent;
+import javax.swing.filechooser.FileSystemView;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.Callable;
 
 /**
  * Basic implementation of a file list.
@@ -46,7 +50,7 @@
     private JFileChooser filechooser = null;
     // PENDING(jeff) pick the size more sensibly
     private Vector<File> fileCache = new Vector<File>(50);
-    private LoadFilesThread loadThread = null;
+    private FilesLoader filesLoader = null;
     private Vector<File> files = null;
     private Vector<File> directories = null;
     private int fetchID = 0;
@@ -91,10 +95,10 @@
      * This method is used to interrupt file loading thread.
      */
     public void invalidateFileCache() {
-        if (loadThread != null) {
-            loadThread.interrupt();
-            loadThread.cancelRunnables();
-            loadThread = null;
+        if (filesLoader != null) {
+            filesLoader.loadThread.interrupt();
+            filesLoader.cancelRunnables();
+            filesLoader = null;
         }
     }
 
@@ -149,15 +153,14 @@
         if (currentDirectory == null) {
             return;
         }
-        if (loadThread != null) {
-            loadThread.interrupt();
-            loadThread.cancelRunnables();
+        if (filesLoader != null) {
+            filesLoader.loadThread.interrupt();
+            filesLoader.cancelRunnables();
         }
 
         setBusy(true, ++fetchID);
 
-        loadThread = new LoadFilesThread(currentDirectory, fetchID);
-        loadThread.start();
+        filesLoader = new FilesLoader(currentDirectory, fetchID);
     }
 
     /**
@@ -251,17 +254,25 @@
     }
 
 
-    class LoadFilesThread extends Thread {
+    class FilesLoader implements Runnable {
         File currentDirectory = null;
         int fid;
         Vector<DoChangeContents> runnables = new Vector<DoChangeContents>(10);
+        final Thread loadThread;
 
-        public LoadFilesThread(File currentDirectory, int fid) {
-            super("Basic L&F File Loading Thread");
+        public FilesLoader(File currentDirectory, int fid) {
             this.currentDirectory = currentDirectory;
             this.fid = fid;
+            String name = "Basic L&F File Loading Thread";
+            if (System.getSecurityManager() == null) {
+                this.loadThread = new Thread(this, name);
+            } else {
+                this.loadThread = new ManagedLocalsThread(this, name);
+            }
+            this.loadThread.start();
         }
 
+        @Override
         public void run() {
             run0();
             setBusy(false, fid);
@@ -270,13 +281,13 @@
         public void run0() {
             FileSystemView fileSystem = filechooser.getFileSystemView();
 
-            if (isInterrupted()) {
+            if (loadThread.isInterrupted()) {
                 return;
             }
 
             File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
 
-            if (isInterrupted()) {
+            if (loadThread.isInterrupted()) {
                 return;
             }
 
@@ -296,7 +307,7 @@
                         newFiles.addElement(file);
                     }
 
-                    if (isInterrupted()) {
+                    if (loadThread.isInterrupted()) {
                         return;
                     }
                 }
@@ -333,7 +344,7 @@
                         }
                         if (start >= 0 && end > start
                             && newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) {
-                            if (isInterrupted()) {
+                            if (loadThread.isInterrupted()) {
                                 return null;
                             }
                             return new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid);
@@ -351,14 +362,14 @@
                         }
                         if (start >= 0 && end > start
                             && fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) {
-                            if (isInterrupted()) {
+                            if (loadThread.isInterrupted()) {
                                 return null;
                             }
                             return new DoChangeContents(null, 0, new Vector<>(fileCache.subList(start, end)), start, fid);
                         }
                     }
                     if (!fileCache.equals(newFileCache)) {
-                        if (isInterrupted()) {
+                        if (loadThread.isInterrupted()) {
                             cancelRunnables(runnables);
                         }
                         return new DoChangeContents(newFileCache, 0, fileCache, 0, fid);
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Fri Apr 03 17:17:36 2015 +0300
@@ -68,6 +68,7 @@
 import sun.awt.AppContext;
 
 
+import sun.misc.ManagedLocalsThread;
 import sun.swing.PrintingStatus;
 import sun.swing.SwingUtilities2;
 import sun.swing.text.TextComponentPrintable;
@@ -2363,7 +2364,11 @@
             runnablePrinting.run();
         } else {
             if (isEventDispatchThread) {
-                (new Thread(runnablePrinting)).start();
+                if (System.getSecurityManager() == null) {
+                    new Thread(runnablePrinting).start();
+                } else {
+                    new ManagedLocalsThread(runnablePrinting).start();
+                }
                 printingStatus.showModal(true);
             } else {
                 printingStatus.showModal(false);
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Fri Apr 03 17:17:36 2015 +0300
@@ -26,6 +26,7 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
+import sun.misc.ManagedLocalsThread;
 
 /**
  * A queue of text layout tasks.
@@ -80,7 +81,22 @@
      */
     public synchronized void addTask(Runnable task) {
         if (worker == null) {
-            worker = new LayoutThread();
+            Runnable workerRunnable = () -> {
+                Runnable work;
+                do {
+                    work = waitForWork();
+                    if (work != null) {
+                        work.run();
+                    }
+                } while (work != null);
+            };
+            String name =  "text-layout";
+            if (System.getSecurityManager() == null) {
+                worker = new Thread(workerRunnable, name);
+            } else {
+                worker = new ManagedLocalsThread(workerRunnable, name);
+            }
+            worker.setPriority(Thread.MIN_PRIORITY);
             worker.start();
         }
         tasks.addElement(task);
@@ -102,28 +118,4 @@
         tasks.removeElementAt(0);
         return work;
     }
-
-    /**
-     * low priority thread to perform layout work forever
-     */
-    class LayoutThread extends Thread {
-
-        LayoutThread() {
-            super("text-layout");
-            setPriority(Thread.MIN_PRIORITY);
-        }
-
-        public void run() {
-            Runnable work;
-            do {
-                work = waitForWork();
-                if (work != null) {
-                    work.run();
-                }
-            } while (work != null);
-        }
-
-
-    }
-
 }
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Fri Apr 03 17:17:36 2015 +0300
@@ -52,6 +52,7 @@
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 import sun.misc.IOUtils;
+import sun.misc.ManagedLocalsThread;
 import sun.net.www.ParseUtil;
 import sun.security.util.SecurityConstants;
 
@@ -855,13 +856,13 @@
  * this operation to complete before continuing, wait for the notifyAll()
  * operation on the syncObject to occur.
  */
-class AppContextCreator extends Thread  {
+class AppContextCreator extends ManagedLocalsThread {
     Object syncObject = new Object();
     AppContext appContext = null;
     volatile boolean created = false;
 
     AppContextCreator(ThreadGroup group)  {
-        super(group, "AppContextCreator");
+        super(group, null, "AppContextCreator");
     }
 
     public void run()  {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Fri Apr 03 17:17:36 2015 +0300
@@ -42,6 +42,7 @@
 import sun.awt.AppContext;
 import sun.awt.EmbeddedFrame;
 import sun.awt.SunToolkit;
+import sun.misc.ManagedLocalsThread;
 import sun.misc.MessageUtils;
 import sun.misc.PerformanceLogger;
 import sun.misc.Queue;
@@ -176,8 +177,7 @@
 
 
         ThreadGroup appletGroup = loader.getThreadGroup();
-
-        handler = new Thread(appletGroup, this, "thread " + nm);
+        handler = new ManagedLocalsThread(appletGroup, this, "thread " + nm);
         // set the context class loader for this thread
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
                 @Override
@@ -410,7 +410,7 @@
                       if (loaderThread == null) {
                           // REMIND: do we want a name?
                           //System.out.println("------------------- loading applet");
-                          setLoaderThread(new Thread(this));
+                          setLoaderThread(new ManagedLocalsThread(this));
                           loaderThread.start();
                           // we get to go to sleep while this runs
                           loaderThread.join();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -38,6 +38,7 @@
 import java.security.PrivilegedAction;
 import sun.awt.SunToolkit;
 import sun.awt.AppContext;
+import sun.misc.ManagedLocalsThread;
 
 /**
  * A frame to show the applet tag in.
@@ -853,7 +854,7 @@
         //
         final AppletPanel p = panel;
 
-        new Thread(new Runnable()
+        new ManagedLocalsThread(new Runnable()
         {
             @Override
             public void run()
@@ -889,7 +890,7 @@
         // spawn a new thread to avoid blocking the event queue
         // when calling appletShutdown.
         //
-        new Thread(new Runnable()
+        new ManagedLocalsThread(new Runnable()
         {
             @Override
             public void run()
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Fri Apr 03 17:17:36 2015 +0300
@@ -34,6 +34,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import sun.misc.InnocuousThread;
 import sun.util.logging.PlatformLogger;
 import sun.awt.util.ThreadGroupUtils;
 
@@ -340,7 +341,13 @@
      * Must be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
      */
     private void activateBlockerThread() {
-        Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown");
+        Thread thread;
+        String name =  "AWT-Shutdown";
+        if (System.getSecurityManager() == null) {
+            thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, name);
+        } else {
+            thread = new InnocuousThread(this, name);
+        }
         thread.setContextClassLoader(null);
         thread.setDaemon(false);
         blockerThread = thread;
--- a/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Fri Apr 03 17:17:36 2015 +0300
@@ -43,6 +43,8 @@
 import java.beans.PropertyChangeSupport;
 import java.beans.PropertyChangeListener;
 import java.lang.ref.SoftReference;
+
+import sun.misc.InnocuousThread;
 import sun.util.logging.PlatformLogger;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
@@ -589,7 +591,12 @@
         }
 
         public Thread run() {
-            Thread t = new Thread(appContext.getThreadGroup(), runnable);
+            Thread t;
+            if (System.getSecurityManager() == null) {
+                t = new Thread(appContext.getThreadGroup(), runnable);
+            } else {
+                t = new InnocuousThread(appContext.getThreadGroup(), runnable, "AppContext Disposer");
+            }
             t.setContextClassLoader(appContext.getContextClassLoader());
             t.setPriority(Thread.NORM_PRIORITY + 1);
             t.setDaemon(true);
--- a/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Fri Apr 03 17:17:36 2015 +0300
@@ -55,6 +55,8 @@
 import java.util.prefs.Preferences;
 import sun.awt.InputMethodSupport;
 import sun.awt.SunToolkit;
+import sun.misc.InnocuousThread;
+import sun.misc.ManagedLocalsThread;
 
 /**
  * <code>InputMethodManager</code> is an abstract class that manages the input
@@ -165,7 +167,12 @@
                 // to choose from. Otherwise, just keep the instance.
                 if (imm.hasMultipleInputMethods()) {
                     imm.initialize();
-                    Thread immThread = new Thread(imm, threadName);
+                    Thread immThread;
+                    if (System.getSecurityManager() == null) {
+                        immThread = new Thread(imm, threadName);
+                    } else {
+                        immThread = new ManagedLocalsThread(imm, threadName);
+                    }
                     immThread.setDaemon(true);
                     immThread.setPriority(Thread.NORM_PRIORITY + 1);
                     immThread.start();
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Fri Apr 03 17:17:36 2015 +0300
@@ -27,6 +27,7 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
+import sun.misc.ManagedLocalsThread;
 
 /**
   * An ImageFetcher is a thread used to fetch ImageFetchable objects.
@@ -41,7 +42,7 @@
   * @author Jim Graham
   * @author Fred Ecks
   */
-class ImageFetcher extends Thread {
+class ImageFetcher extends ManagedLocalsThread {
     static final int HIGH_PRIORITY = 8;
     static final int LOW_PRIORITY = 3;
     static final int ANIM_PRIORITY = 2;
@@ -54,7 +55,7 @@
       * Constructor for ImageFetcher -- only called by add() below.
       */
     private ImageFetcher(ThreadGroup threadGroup, int index) {
-        super(threadGroup, "Image Fetcher " + index);
+        super(threadGroup, null, "Image Fetcher " + index);
         setDaemon(true);
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Fri Apr 03 17:17:36 2015 +0300
@@ -36,6 +36,7 @@
 
 import sun.awt.AppContext;
 import sun.awt.util.ThreadGroupUtils;
+import sun.misc.InnocuousThread;
 
 public class CreatedFontTracker {
 
@@ -115,18 +116,25 @@
         static void init() {
             if (t == null) {
                 // Add a shutdown hook to remove the temp file.
-                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;
-                        });
+                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                    if (System.getSecurityManager() == null) {
+                        /* 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);
+                    } else {
+                        /* InnocuousThread is a member of a correct TG by default */
+                        t = new InnocuousThread(TempFileDeletionHook::runHooks);
+                    }
+                    /* Set context class loader to null in order to avoid
+                     * keeping a strong reference to an application classloader.
+                     */
+                    t.setContextClassLoader(null);
+                    Runtime.getRuntime().addShutdownHook(t);
+                    return null;
+                });
             }
         }
 
--- a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Fri Apr 03 17:17:36 2015 +0300
@@ -54,6 +54,7 @@
 import sun.awt.SunToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.FontSupport;
+import sun.misc.InnocuousThread;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -2529,18 +2530,17 @@
                           });
                       }
                     };
-                    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;
-                            });
+                    AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                        if (System.getSecurityManager() == null) {
+                            ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                            fileCloser = new Thread(rootTG, fileCloserRunnable);
+                        } else {
+                            fileCloser = new InnocuousThread(fileCloserRunnable);
+                        }
+                        fileCloser.setContextClassLoader(null);
+                        Runtime.getRuntime().addShutdownHook(fileCloser);
+                        return null;
+                    });
                 }
             }
         }
--- a/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -26,6 +26,7 @@
 package sun.java2d;
 
 import sun.awt.util.ThreadGroupUtils;
+import sun.misc.InnocuousThread;
 
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
@@ -81,21 +82,21 @@
             }
         }
         disposerInstance = new Disposer();
-        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;
-                 }
-         );
+        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+            String name = "Java2D Disposer";
+            Thread t;
+            if (System.getSecurityManager() == null) {
+                ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
+                t = new Thread(rootTG, disposerInstance, name);
+            } else {
+                t = new InnocuousThread(disposerInstance, name);
+            }
+            t.setContextClassLoader(null);
+            t.setDaemon(true);
+            t.setPriority(Thread.MAX_PRIORITY);
+            t.start();
+            return null;
+        });
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Fri Apr 03 17:17:36 2015 +0300
@@ -33,6 +33,7 @@
 import java.awt.AlphaComposite;
 import java.awt.Rectangle;
 import sun.awt.image.BufImgSurfaceData;
+import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.SurfaceData;
 import sun.java2d.pipe.Region;
 import java.lang.reflect.Field;
@@ -46,6 +47,8 @@
 import java.io.FileNotFoundException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+
+import sun.misc.InnocuousThread;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -413,15 +416,19 @@
         return traceout;
     }
 
-    public static class TraceReporter extends Thread {
+    public static class TraceReporter implements Runnable {
         public static void setShutdownHook() {
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                public Void run() {
-                    TraceReporter t = new TraceReporter();
-                    t.setContextClassLoader(null);
-                    Runtime.getRuntime().addShutdownHook(t);
-                    return null;
+            AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                TraceReporter t = new TraceReporter();
+                Thread thread;
+                if (System.getSecurityManager() == null) {
+                    thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), t);
+                } else {
+                    thread = new InnocuousThread(t);
                 }
+                thread.setContextClassLoader(null);
+                Runtime.getRuntime().addShutdownHook(thread);
+                return null;
             });
         }
 
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Fri Apr 03 17:17:36 2015 +0300
@@ -28,6 +28,8 @@
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.pipe.RenderBuffer;
 import sun.java2d.pipe.RenderQueue;
+import sun.misc.InnocuousThread;
+
 import static sun.java2d.pipe.BufferedOpCodes.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -48,9 +50,7 @@
          * The thread must be a member of a thread group
          * which will not get GCed before VM exit.
          */
-        flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) () -> {
-            return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup());
-        });
+        flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new);
     }
 
     /**
@@ -115,7 +115,7 @@
      * Returns true if the current thread is the OGL QueueFlusher thread.
      */
     public static boolean isQueueFlusherThread() {
-        return (Thread.currentThread() == getInstance().flusher);
+        return (Thread.currentThread() == getInstance().flusher.thread);
     }
 
     public void flushNow() {
@@ -153,16 +153,22 @@
         refSet.clear();
     }
 
-    private class QueueFlusher extends Thread {
+    private class QueueFlusher implements Runnable {
         private boolean needsFlush;
         private Runnable task;
         private Error error;
+        private final Thread thread;
 
-        public QueueFlusher(ThreadGroup threadGroup) {
-            super(threadGroup, "Java2D Queue Flusher");
-            setDaemon(true);
-            setPriority(Thread.MAX_PRIORITY);
-            start();
+        public QueueFlusher() {
+            String name = "Java2D Queue Flusher";
+            if (System.getSecurityManager() == null) {
+                this.thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, name);
+            } else {
+                this.thread = new InnocuousThread(this, name);
+            }
+            thread.setDaemon(true);
+            thread.setPriority(Thread.MAX_PRIORITY);
+            thread.start();
         }
 
         public synchronized void flushNow() {
--- a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Fri Apr 03 17:17:36 2015 +0300
@@ -71,6 +71,7 @@
 import javax.print.attribute.standard.MediaSizeName;
 import javax.print.attribute.standard.PageRanges;
 
+import sun.misc.ManagedLocalsThread;
 import sun.print.SunPageSelection;
 import sun.print.SunMinMaxPage;
 
@@ -986,8 +987,12 @@
     }
 
     private void startPrinterJobThread() {
-
-        printerJobThread = new Thread(this, "printerJobThread");
+        String name = "printerJobThread";
+        if (System.getSecurityManager() == null) {
+            printerJobThread = new Thread(this, name);
+        } else {
+            printerJobThread = new ManagedLocalsThread(this, name);
+        }
         printerJobThread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,8 @@
 
 package sun.print;
 
+import sun.misc.ManagedLocalsThread;
+
 import java.util.Vector;
 
 import javax.print.PrintService;
@@ -40,7 +42,7 @@
  * to obtain the state of the attributes and notifies the listeners of
  * any changes.
  */
-class ServiceNotifier extends Thread {
+class ServiceNotifier extends ManagedLocalsThread {
 
     private PrintService service;
     private Vector<PrintServiceAttributeListener> listeners;
@@ -48,7 +50,7 @@
     private PrintServiceAttributeSet lastSet;
 
     ServiceNotifier(PrintService service) {
-        super(service.getName() + " notifier");
+        super((Runnable) null, service.getName() + " notifier");
         this.service = service;
         listeners = new Vector<>();
         try {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -29,6 +29,7 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import sun.awt.AWTAccessor;
+import sun.misc.ManagedLocalsThread;
 
 /**
  * FileDialogPeer for the GtkFileChooser.
@@ -111,13 +112,16 @@
         XToolkit.awtLock();
         try {
             if (b) {
-                Thread t = new Thread() {
-                    public void run() {
-                        showNativeDialog();
-                        fd.setVisible(false);
-                    }
+                Runnable task = () -> {
+                    showNativeDialog();
+                    fd.setVisible(false);
                 };
-                t.start();
+                if (System.getSecurityManager() == null) {
+                    new Thread(task).start();
+                } else {
+                    new ManagedLocalsThread(task).start();
+                }
+
             } else {
                 quit();
                 fd.setVisible(false);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Fri Apr 03 17:17:36 2015 +0300
@@ -29,6 +29,9 @@
 import java.awt.event.*;
 import java.awt.peer.TrayIconPeer;
 import sun.awt.*;
+import sun.misc.InnocuousThread;
+import sun.misc.ManagedLocalsThread;
+
 import java.awt.image.*;
 import java.text.BreakIterator;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -338,7 +341,7 @@
                 lineLabels[i].setBackground(Color.white);
             }
 
-            displayer.start();
+            displayer.thread.start();
         }
 
         public void display(String caption, String text, String messageType) {
@@ -415,7 +418,7 @@
         }
 
         public void dispose() {
-            displayer.interrupt();
+            displayer.thread.interrupt();
             super.dispose();
         }
 
@@ -444,16 +447,23 @@
             }
         }
 
-        private class Displayer extends Thread {
+        private class Displayer implements Runnable {
             final int MAX_CONCURRENT_MSGS = 10;
 
             ArrayBlockingQueue<Message> messageQueue = new ArrayBlockingQueue<Message>(MAX_CONCURRENT_MSGS);
             boolean isDisplayed;
+            final Thread thread;
 
             Displayer() {
-                setDaemon(true);
+                if (System.getSecurityManager() == null) {
+                    this.thread = new Thread(this);
+                } else {
+                    this.thread = new ManagedLocalsThread(this);
+                }
+                this.thread.setDaemon(true);
             }
 
+            @Override
             public void run() {
                 while (true) {
                     Message msg = null;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Fri Apr 03 17:17:36 2015 +0300
@@ -266,21 +266,26 @@
             awtUnlock();
         }
         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();
-                        }
-                        freeXKB();
-                        if (log.isLoggable(PlatformLogger.Level.FINE)) {
-                            dumpPeers();
-                        }
-                    }
-                };
+            Runnable r = () -> {
+                XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
+                if (peer != null) {
+                    peer.dispose();
+                }
+                if (xs != null) {
+                    ((XAWTXSettings)xs).dispose();
+                }
+                freeXKB();
+                if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                    dumpPeers();
+                }
+            };
+            String name = "XToolkt-Shutdown-Thread";
+            Thread shutdownThread;
+            if (System.getSecurityManager() == null) {
+                shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name);
+            } else {
+                shutdownThread = new InnocuousThread(r, name);
+            }
             shutdownThread.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdownThread);
             return null;
@@ -326,7 +331,13 @@
             XWM.init();
 
             toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
-                Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT");
+                String name = "AWT-XAWT";
+                Thread thread;
+                if (System.getSecurityManager() == null) {
+                    thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, name);
+                } else {
+                    thread = new InnocuousThread(XToolkit.this, name);
+                }
                 thread.setContextClassLoader(null);
                 thread.setPriority(Thread.NORM_PRIORITY + 1);
                 thread.setDaemon(true);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Fri Apr 03 17:17:36 2015 +0300
@@ -43,6 +43,7 @@
 import sun.java2d.loops.SurfaceType;
 
 import sun.awt.util.ThreadGroupUtils;
+import sun.misc.InnocuousThread;
 
 /**
  * This is an implementation of a GraphicsDevice object for a single
@@ -428,7 +429,6 @@
             // hook will have no effect)
             shutdownHookRegistered = true;
             PrivilegedAction<Void> a = () -> {
-                ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
                 Runnable r = () -> {
                     Window old = getFullScreenWindow();
                     if (old != null) {
@@ -436,7 +436,13 @@
                         setDisplayMode(origDisplayMode);
                     }
                 };
-                Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen);
+                String name = "Display-Change-Shutdown-Thread-" + screen;
+                Thread t;
+                if (System.getSecurityManager() == null) {
+                    t = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name);
+                } else {
+                    t = new InnocuousThread(r, name);
+                }
                 t.setContextClassLoader(null);
                 Runtime.getRuntime().addShutdownHook(t);
                 return null;
--- a/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,8 @@
 
 package sun.print;
 
+import sun.misc.ManagedLocalsThread;
+
 import java.io.BufferedReader;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -211,7 +213,12 @@
     public PrintServiceLookupProvider() {
         // start the printer listener thread
         if (pollServices) {
-            PrinterChangeListener thr = new PrinterChangeListener();
+            Thread thr;
+            if (System.getSecurityManager() == null) {
+                thr = new Thread(new PrinterChangeListener());
+            } else {
+                thr = new ManagedLocalsThread(new PrinterChangeListener());
+            }
             thr.setDaemon(true);
             thr.start();
             IPPPrintService.debug_println(debugPrefix+"polling turned on");
@@ -934,8 +941,9 @@
         }
     }
 
-    private class PrinterChangeListener extends Thread {
+    private class PrinterChangeListener implements Runnable {
 
+        @Override
         public void run() {
             int refreshSecs;
             while (true) {
@@ -954,7 +962,7 @@
                     refreshSecs = minRefreshTime;
                 }
                 try {
-                    sleep(refreshSecs * 1000);
+                    Thread.sleep(refreshSecs * 1000);
                 } catch (InterruptedException e) {
                     break;
                 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Fri Apr 03 17:17:36 2015 +0300
@@ -41,6 +41,7 @@
 import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
 import sun.awt.util.ThreadGroupUtils;
+import sun.misc.InnocuousThread;
 
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
@@ -516,26 +517,22 @@
         private static Thread comThread;
 
         private ComInvoker() {
-            super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
+            super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<>());
             allowCoreThreadTimeOut(false);
             setThreadFactory(this);
-            final Runnable shutdownHook = new Runnable() {
-                public void run() {
-                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                        public Void run() {
-                            shutdownNow();
-                            return null;
-                        }
-                    });
+            final Runnable shutdownHook = () -> AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                shutdownNow();
+                return null;
+            });
+            AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                Thread t;
+                if (System.getSecurityManager() == null) {
+                    t = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownHook);
+                } else {
+                    t = new InnocuousThread(shutdownHook);
                 }
-            };
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                public Void run() {
-                    Runtime.getRuntime().addShutdownHook(
-                        new Thread(shutdownHook)
-                    );
-                    return null;
-                }
+                Runtime.getRuntime().addShutdownHook(t);
+                return null;
             });
         }
 
@@ -550,17 +547,22 @@
                     }
                 }
             };
-            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 rootTG = ThreadGroupUtils.getRootThreadGroup();
-                            Thread thread = new Thread(rootTG, comRun, "Swing-Shell");
-                            thread.setDaemon(true);
-                            return thread;
-                        }
-                );
+            comThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
+                String name = "Swing-Shell";
+                Thread thread;
+                if (System.getSecurityManager() == null) {
+                     /* 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.
+                      */
+                    thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), comRun, name);
+                } else {
+                    /* InnocuousThread is a member of a correct TG by default */
+                    thread = new InnocuousThread(comRun, name);
+                }
+                thread.setDaemon(true);
+                return thread;
+            });
             return comThread;
         }
 
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -36,6 +36,7 @@
 import java.util.Vector;
 import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
+import sun.misc.ManagedLocalsThread;
 
 final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
 
@@ -97,12 +98,11 @@
 
     @Override
     public void show() {
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                _show();
-            }
-        }).start();
+        if (System.getSecurityManager() == null) {
+            new Thread(this::_show).start();
+        } else {
+            new ManagedLocalsThread(this::_show).start();
+        }
     }
 
     @Override
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,8 @@
 
 package sun.awt.windows;
 
+import sun.misc.ManagedLocalsThread;
+
 final class WPageDialogPeer extends WPrintDialogPeer {
 
     WPageDialogPeer(WPageDialog target) {
@@ -39,20 +41,22 @@
 
     @Override
     public void show() {
-        new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    // Call pageSetup even with no printer installed, this
-                    // will display Windows error dialog and return false.
-                    try {
-                        ((WPrintDialog)target).setRetVal(_show());
-                    } catch (Exception e) {
-                     // No exception should be thrown by native dialog code,
-                     // but if it is we need to trap it so the thread does
-                     // not hide is called and the thread doesn't hang.
-                    }
-                    ((WPrintDialog)target).setVisible(false);
-                }
-            }).start();
+        Runnable runnable = () -> {
+            // Call pageSetup even with no printer installed, this
+            // will display Windows error dialog and return false.
+            try {
+                ((WPrintDialog)target).setRetVal(_show());
+            } catch (Exception e) {
+                // No exception should be thrown by native dialog code,
+                // but if it is we need to trap it so the thread does
+                // not hide is called and the thread doesn't hang.
+            }
+            ((WPrintDialog)target).setVisible(false);
+        };
+        if (System.getSecurityManager() == null) {
+            new Thread(runnable).start();
+        } else {
+            new ManagedLocalsThread(runnable).start();
+        }
     }
 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Fri Apr 03 17:17:36 2015 +0300
@@ -32,6 +32,7 @@
 import java.util.Vector;
 import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
+import sun.misc.ManagedLocalsThread;
 
 class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
 
@@ -67,19 +68,21 @@
 
     @Override
     public void show() {
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ((WPrintDialog)target).setRetVal(_show());
-                } catch (Exception e) {
-                    // No exception should be thrown by native dialog code,
-                    // but if it is we need to trap it so the thread does
-                    // not hide is called and the thread doesn't hang.
-                }
-                ((WPrintDialog)target).setVisible(false);
+        Runnable runnable = () -> {
+            try {
+                ((WPrintDialog)target).setRetVal(_show());
+            } catch (Exception e) {
+                // No exception should be thrown by native dialog code,
+                // but if it is we need to trap it so the thread does
+                // not hide is called and the thread doesn't hang.
             }
-        }).start();
+            ((WPrintDialog)target).setVisible(false);
+        };
+        if (System.getSecurityManager() == null) {
+            new Thread(runnable).start();
+        } else {
+            new ManagedLocalsThread(runnable).start();
+        }
     }
 
     synchronized void setHWnd(long hwnd) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Fri Apr 03 17:17:36 2015 +0300
@@ -49,6 +49,7 @@
 import sun.java2d.d3d.D3DRenderQueue;
 import sun.java2d.opengl.OGLRenderQueue;
 
+import sun.misc.InnocuousThread;
 import sun.print.PrintJob2D;
 
 import java.awt.dnd.DragSource;
@@ -247,11 +248,17 @@
          */
         AWTAutoShutdown.notifyToolkitThreadBusy();
 
-        // Find a root TG and attach Appkit thread to it
+        // Find a root TG and attach toolkit thread to it
         ThreadGroup rootTG = AccessController.doPrivileged(
                 (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
         if (!startToolkitThread(this, rootTG)) {
-            Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows");
+            String name = "AWT-Windows";
+            Thread toolkitThread;
+            if (System.getSecurityManager() == null) {
+                toolkitThread = new Thread(rootTG, this, name);
+            } else {
+                toolkitThread = new InnocuousThread(this, name);
+            }
             toolkitThread.setDaemon(true);
             toolkitThread.start();
         }
@@ -278,7 +285,12 @@
 
     private void registerShutdownHook() {
         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-            Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
+            Thread shutdown;
+            if (System.getSecurityManager() == null) {
+                shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
+            } else {
+                shutdown = new InnocuousThread(this::shutdown);
+            }
             shutdown.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdown);
             return null;
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Fri Apr 03 17:17:36 2015 +0300
@@ -48,6 +48,7 @@
 import sun.java2d.windows.GDIWindowSurfaceData;
 import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData;
 import sun.java2d.windows.WindowsFlags;
+import sun.misc.InnocuousThread;
 
 /**
  * This class handles rendering to the screen with the D3D pipeline.
@@ -92,22 +93,25 @@
 
     public D3DScreenUpdateManager() {
         done = false;
-        AccessController.doPrivileged(
-                (PrivilegedAction<Void>) () -> {
-                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-                    Thread shutdown = new Thread(rootTG, () -> {
-                        done = true;
-                        wakeUpUpdateThread();
-                    });
-                    shutdown.setContextClassLoader(null);
-                    try {
-                        Runtime.getRuntime().addShutdownHook(shutdown);
-                    } catch (Exception e) {
-                        done = true;
-                    }
-                    return null;
-                }
-        );
+        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+            Runnable shutdownRunnable = () -> {
+                done = true;
+                wakeUpUpdateThread();
+            };
+            Thread shutdown;
+            if (System.getSecurityManager() == null) {
+                shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            } else {
+                shutdown = new InnocuousThread(shutdownRunnable);
+            }
+            shutdown.setContextClassLoader(null);
+            try {
+                Runtime.getRuntime().addShutdownHook(shutdown);
+            } catch (Exception e) {
+                done = true;
+            }
+            return null;
+        });
     }
 
     /**
@@ -345,17 +349,21 @@
      */
     private synchronized void startUpdateThread() {
         if (screenUpdater == null) {
-            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 = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
+                Thread t;
+                String name = "D3D Screen Updater";
+                if (System.getSecurityManager() == null) {
+                    t = new Thread(ThreadGroupUtils.getRootThreadGroup(),
+                            D3DScreenUpdateManager.this,
+                            name);
+                } else {
+                    t = new InnocuousThread(D3DScreenUpdateManager.this, name);
+                }
+                // REMIND: should it be higher?
+                t.setPriority(Thread.NORM_PRIORITY + 2);
+                t.setDaemon(true);
+                return t;
+            });
             screenUpdater.start();
         } else {
             wakeUpUpdateThread();
--- a/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Fri Aug 01 13:31:03 2014 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Fri Apr 03 17:17:36 2015 +0300
@@ -25,6 +25,8 @@
 
 package sun.print;
 
+import sun.misc.ManagedLocalsThread;
+
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -97,7 +99,12 @@
                 return;
             }
             // start the printer listener thread
-            PrinterChangeListener thr = new PrinterChangeListener();
+            Thread thr;
+            if (System.getSecurityManager() == null) {
+                thr = new Thread(new PrinterChangeListener());
+            } else {
+                thr = new ManagedLocalsThread(new PrinterChangeListener());
+            }
             thr.setDaemon(true);
             thr.start();
         } /* else condition ought to never happen! */
@@ -316,12 +323,13 @@
         return defaultPrintService;
     }
 
-    class PrinterChangeListener extends Thread {
+    class PrinterChangeListener implements Runnable {
         long chgObj;
         PrinterChangeListener() {
             chgObj = notifyFirstPrinterChange(null);
         }
 
+        @Override
         public void run() {
             if (chgObj != -1) {
                 while (true) {