diff --git a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 959b03868fb964422de7471a2ac9bc6b9ce4efbc..ce63adfdf9cedd6f91a6e7d037cc69c6cdc66996 100644 --- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -444,8 +444,12 @@ public final class LWCToolkit extends LWToolkit { } // Intended to be called from the LWCToolkit.m only. - private static void installToolkitThreadNameInJava() { + private static void installToolkitThreadInJava() { Thread.currentThread().setName(CThreading.APPKIT_THREAD_NAME); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread.currentThread().setContextClassLoader(null); + return null; + }); } @Override diff --git a/src/macosx/native/sun/awt/LWCToolkit.m b/src/macosx/native/sun/awt/LWCToolkit.m index 1c24279af1ff7862365cd5b4e04e560e1815d269..9c9a0c21c0d70e03e64934341e6177a4eecc3b80 100644 --- a/src/macosx/native/sun/awt/LWCToolkit.m +++ b/src/macosx/native/sun/awt/LWCToolkit.m @@ -193,10 +193,10 @@ Java_sun_lwawt_macosx_LWCToolkit_initIDs JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit"); - static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadNameInJava, jc_LWCToolkit, "installToolkitThreadNameInJava", "()V"); - JNFCallStaticVoidMethod(env, jsm_installToolkitThreadNameInJava); + static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadInJava, jc_LWCToolkit, "installToolkitThreadInJava", "()V"); + JNFCallStaticVoidMethod(env, jsm_installToolkitThreadInJava); }); - + gNumberOfButtons = sun_lwawt_macosx_LWCToolkit_BUTTONS; jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent"); diff --git a/src/macosx/native/sun/awt/awt.m b/src/macosx/native/sun/awt/awt.m index 0a491fd44f25aea91c46a2654725880362eb2559..5abfca6a760bdaa63508a1e37e9923ebefd5ff02 100644 --- a/src/macosx/native/sun/awt/awt.m +++ b/src/macosx/native/sun/awt/awt.m @@ -434,6 +434,15 @@ JNF_COCOA_ENTER(env); forceEmbeddedMode = YES; } + JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; + jclass jc_SunToolkit = (*env)->FindClass(env, "sun/awt/SunToolkit"); + jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_SunToolkit, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;"); + jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_SunToolkit, sjm_getRootThreadGroup); + appkitThreadGroup = (*env)->NewGlobalRef(env, rootThreadGroup); + // The current thread was attached in getJNIEnvUnchached. + // Detach it back. It will be reattached later if needed with a proper TG + [ThreadUtilities detachCurrentThread]; + BOOL headless = isHeadless(env); // We need to let Foundation know that this is a multithreaded application, if it isn't already. diff --git a/src/macosx/native/sun/osxapp/ThreadUtilities.h b/src/macosx/native/sun/osxapp/ThreadUtilities.h index 2ee65e94c65c349db7e49353886d88310ec797f7..d3a7fe74407508aa5b20f9949b5c4b52757650b4 100644 --- a/src/macosx/native/sun/osxapp/ThreadUtilities.h +++ b/src/macosx/native/sun/osxapp/ThreadUtilities.h @@ -122,11 +122,15 @@ do { \ #endif /* AWT_THREAD_ASSERTS */ // -------------------------------------------------------------------------- +// Set from JNI_Onload +extern jobject appkitThreadGroup; + __attribute__((visibility("default"))) @interface ThreadUtilities { } + (JNIEnv*)getJNIEnv; + (JNIEnv*)getJNIEnvUncached; ++ (void)detachCurrentThread; //Wrappers for the corresponding JNFRunLoop methods with a check for main thread + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block; diff --git a/src/macosx/native/sun/osxapp/ThreadUtilities.m b/src/macosx/native/sun/osxapp/ThreadUtilities.m index d431386bbdbc4452597c2fbe610d20b245330367..12202afe73068c627ff48f9b88e9cbd298243a39 100644 --- a/src/macosx/native/sun/osxapp/ThreadUtilities.m +++ b/src/macosx/native/sun/osxapp/ThreadUtilities.m @@ -33,23 +33,40 @@ // 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; + +inline void attachCurrentThread(void** env) { + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_2; + args.name = NULL; // Set from LWCToolkit + if ([NSThread isMainThread]) { + args.group = appkitThreadGroup; + } else { + args.group = NULL; + } + (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args); +} @implementation ThreadUtilities + (JNIEnv*)getJNIEnv { AWT_ASSERT_APPKIT_THREAD; if (appKitEnv == NULL) { - (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&appKitEnv, NULL); + attachCurrentThread((void **)&appKitEnv); } return appKitEnv; } + (JNIEnv*)getJNIEnvUncached { JNIEnv *env = NULL; - (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, nil); + attachCurrentThread((void **)&env); return env; } ++ (void)detachCurrentThread { + (*jvm)->DetachCurrentThread(jvm); +} + + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block { if ([NSThread isMainThread] && wait == YES) { block(); diff --git a/src/share/classes/sun/awt/AWTAutoShutdown.java b/src/share/classes/sun/awt/AWTAutoShutdown.java index fca64f89ec670215d8a1b8bb78410325c900e395..39a1902b14fe85cd9bfe4be5efde23ef94f30042 100644 --- a/src/share/classes/sun/awt/AWTAutoShutdown.java +++ b/src/share/classes/sun/awt/AWTAutoShutdown.java @@ -27,6 +27,8 @@ package sun.awt; import java.awt.AWTEvent; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Collections; import java.util.HashSet; import java.util.IdentityHashMap; @@ -333,7 +335,11 @@ public final class AWTAutoShutdown implements Runnable { * the new blocker thread starts. */ private void activateBlockerThread() { - Thread thread = new Thread(this, "AWT-Shutdown"); + Thread thread = new Thread(SunToolkit.getRootThreadGroup(), this, "AWT-Shutdown"); + AccessController.doPrivileged((PrivilegedAction) () -> { + thread.setContextClassLoader(null); + return null; + }); thread.setDaemon(false); blockerThread = thread; thread.start(); diff --git a/src/share/classes/sun/awt/SunToolkit.java b/src/share/classes/sun/awt/SunToolkit.java index 8341bdf870d3ced0daaed63c1c6fb885cf1f8943..364bab0edbe36008b111c9e37744b5a293c41841 100644 --- a/src/share/classes/sun/awt/SunToolkit.java +++ b/src/share/classes/sun/awt/SunToolkit.java @@ -37,6 +37,7 @@ import java.awt.TrayIcon; import java.awt.SystemTray; import java.awt.event.InputEvent; import java.net.URL; +import java.security.PrivilegedAction; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; @@ -1115,6 +1116,17 @@ public abstract class SunToolkit extends Toolkit return startupLocale; } + protected static ThreadGroup getRootThreadGroup() { + return AccessController.doPrivileged((PrivilegedAction) () -> { + 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 */ diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java index 303842300342cfbe80c41971960d0ee28e595e9d..a5e780107c93180683b0d7e9f92c2b79ffd4071b 100644 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -256,13 +256,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } PrivilegedAction a = new PrivilegedAction() { public Void run() { - ThreadGroup mainTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = mainTG.getParent(); - while (parentTG != null) { - mainTG = parentTG; - parentTG = mainTG.getParent(); - } - Thread shutdownThread = new Thread(mainTG, "XToolkt-Shutdown-Thread") { + Thread shutdownThread = new Thread(getRootThreadGroup(), "XToolkt-Shutdown-Thread") { public void run() { XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); if (peer != null) { @@ -327,13 +321,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable { PrivilegedAction action = new PrivilegedAction() { public Thread run() { - ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = currentTG.getParent(); - while (parentTG != null) { - currentTG = parentTG; - parentTG = currentTG.getParent(); - } - Thread thread = new Thread(currentTG, XToolkit.this, "AWT-XAWT"); + Thread thread = new Thread(getRootThreadGroup(), XToolkit.this, "AWT-XAWT"); + thread.setContextClassLoader(null); thread.setPriority(Thread.NORM_PRIORITY + 1); thread.setDaemon(true); return thread; diff --git a/src/windows/classes/sun/awt/windows/WToolkit.java b/src/windows/classes/sun/awt/windows/WToolkit.java index 0f67ffe0a50215b6f8a268b9c026af25058d055d..5b1c17fcdb2bfb073c8bb64facb85ea810252c86 100644 --- a/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/src/windows/classes/sun/awt/windows/WToolkit.java @@ -222,7 +222,7 @@ public class WToolkit extends SunToolkit implements Runnable { private static native void postDispose(); - private static native boolean startToolkitThread(Runnable thread); + private static native boolean startToolkitThread(Runnable thread, ThreadGroup rootThreadGroup); public WToolkit() { // Startup toolkit threads @@ -239,8 +239,10 @@ public class WToolkit extends SunToolkit implements Runnable { */ AWTAutoShutdown.notifyToolkitThreadBusy(); - if (!startToolkitThread(this)) { - Thread toolkitThread = new Thread(this, "AWT-Windows"); + // Find a root TG and attach Appkit thread to it + ThreadGroup rootTG = getRootThreadGroup(); + if (!startToolkitThread(this, rootTG)) { + Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows"); toolkitThread.setDaemon(true); toolkitThread.start(); } @@ -270,14 +272,7 @@ public class WToolkit extends SunToolkit implements Runnable { private final void registerShutdownHook() { AccessController.doPrivileged(new PrivilegedAction() { public Void 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() { + Thread shutdown = new Thread(getRootThreadGroup(), new Runnable() { public void run() { shutdown(); } @@ -290,7 +285,11 @@ public class WToolkit extends SunToolkit implements Runnable { } public void run() { - Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread.currentThread().setContextClassLoader(null); + return null; + }); + Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 1); boolean startPump = init(); if (startPump) { diff --git a/src/windows/native/sun/windows/awt_Toolkit.cpp b/src/windows/native/sun/windows/awt_Toolkit.cpp index ba8d6de26739caabb26c94ade39f52fcc7622c04..545219a61c3d84dfb8b115a9d5d6b6f796766b25 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -364,6 +364,7 @@ struct ToolkitThreadProc_Data { HANDLE hCompleted; jobject thread; + jobject threadGroup; }; void ToolkitThreadProc(void *param) @@ -376,7 +377,7 @@ void ToolkitThreadProc(void *param) JavaVMAttachArgs attachArgs; attachArgs.version = JNI_VERSION_1_2; attachArgs.name = "AWT-Windows"; - attachArgs.group = NULL; + attachArgs.group = data->threadGroup; jint res = jvm->AttachCurrentThreadAsDaemon((void **)&env, &attachArgs); if (res < 0) { @@ -415,17 +416,18 @@ void ToolkitThreadProc(void *param) /* * Class: sun_awt_windows_WToolkit * Method: startToolkitThread - * Signature: (Ljava/lang/Runnable;)Z + * Signature: (Ljava/lang/Runnable;Ljava/lang/ThreadGroup)Z */ JNIEXPORT jboolean JNICALL -Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobject thread) +Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobject thread, jobject threadGroup) { AwtToolkit& tk = AwtToolkit::GetInstance(); ToolkitThreadProc_Data data; data.result = false; data.thread = env->NewGlobalRef(thread); - if (data.thread == NULL) { + data.threadGroup = env->NewGlobalRef(threadGroup); + if (data.thread == NULL || data.threadGroup == NULL) { return JNI_FALSE; } data.hCompleted = ::CreateEvent(NULL, FALSE, FALSE, NULL); @@ -443,6 +445,7 @@ Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobjec ::CloseHandle(data.hCompleted); env->DeleteGlobalRef(data.thread); + env->DeleteGlobalRef(data.threadGroup); return result ? JNI_TRUE : JNI_FALSE; }