JDK-8190329 : [macos] Swing InterOp Platform.exit() crash
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8,9,10
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: os_x
  • Submitted: 2017-10-30
  • Updated: 2024-09-24
  • Resolved: 2024-09-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 24
24 b14Fixed
Related Reports
Cloners :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
It is possible to crash Swing by calling Platform.Exit()

import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;

import javax.swing.*;

public class PlatformExitCrash extends Application {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(PlatformExitCrash::createSwing);
        Application.launch(args);
    }

    private static void createSwing() {
        JDialog d = new JDialog();
        Platform.runLater(()-> {
            Platform.exit();
        });
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
        d.setVisible(true);
    }

    @Override
    public void start(Stage st) {
    }
}
Comments
Changeset: 9a1024de Branch: master Author: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: 2024-09-04 05:05:20 +0000 URL: https://git.openjdk.org/jdk/commit/9a1024dec68057c7c581ac0a38fc7f96489a0a76
04-09-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/20688 Date: 2024-08-23 09:17:43 +0000
23-08-2024

> Since it's not going to hamper real use-case, should we close as "Wont fix"/Not an issue Maybe we can close this as "Won't fix". Or lower the priority to P4 and leave it as a Confidential bug in the backlog > or should we wrap the affected methods under some kind of [isAppkitThreadRunning] check? > I thought isMainThread will be false and GetEnv will be null for detached thread but The isMainThread check is an Apple thing. Whether or not the AppKit thread is attached to the JVM, it is still the main AppKit thread. GetEnv should be null if you call it without attaching the thread to the JVM, but you probably don't want to do this everywhere. UPDATE: After further discussion, we should not close this as Won't fix, but should provide a fix.
23-08-2024

> >>Is it the one in GlassApplication.m#runLoop [DetachCurrentThread(jvm)] ? > TO answer my own question, yes it seems if this "DetachCurrentThread" is commented in GlassApplication.m, then crash does not happen Yes, I saw that too. The app will hang because there is no event loop running, but it will no longer crash.
22-08-2024

>>Is it the one in GlassApplication.m#runLoop [DetachCurrentThread(jvm)] ? TO answer my own question, yes it seems if this "DetachCurrentThread" is commented in GlassApplication.m, then crash does not happen JNIEnv *penv = [ThreadUtilities getJNIEnvUncached]; returns 0x158cc5218 and jint ret = (*jvm)->GetEnv(jvm, &pEnv, JNI_VERSION_1_4); returns 0 ie neither env is set to null nor return value is JNI_EDETACHED even though jni spec specifies otherwise.. getJNIEnvUncached tries to attach thread to vm before retireving env, not sure if that is causing EDETACHED not to return. + (JNIEnv*)getJNIEnvUncached { JNIEnv *env = NULL; attachCurrentThread((void **)&env); return env; }
22-08-2024

But I am not sure if the testcase origanization is correct..It spawns a Swing thread and then launch Application ie FX Application thread and calls Platform.exit in Swing execution. [~kcr] Is this PlatformExitCrash.java valid way of calling? I think the logical way of calling should be public class PlatformExitCrash extends Application { public static void main(String[] args) { Application.launch(args); } private static void createSwing() { JDialog d = new JDialog(); try { Thread.sleep(3000); } catch (InterruptedException e) { } d.setVisible(true); try { Thread.sleep(3000); } catch (InterruptedException e) { } Platform.runLater(()-> { Platform.exit(); }); } @Override public void start(Stage st) { st.show(); SwingUtilities.invokeLater(PlatformExitCrash::createSwing); } } which still crashes btw but in MTLLayer V [libjvm.dylib+0x112f154] VMError::report_and_die(Thread*, unsigned int, unsigned char*, void*, void*)+0x0 V [libjvm.dylib+0x54a2d0] print_error_for_unit_test(char const*, char const*, char*)+0x0 V [libjvm.dylib+0x9333f0] jni_NewLocalRef+0x2dc C [libawt_lwawt.dylib+0x6a898] -[MTLLayer blitCallback]+0x210 C [libawt_lwawt.dylib+0x6aa20] -[MTLLayer display]+0x68 C [QuartzCore+0x1fb3c] CA::Layer::display_if_needed(CA::Transaction*)+0x2e0 C [QuartzCore+0x1a4da4] CA::Context::commit_transaction(CA::Transaction*, double, double*)+0x200 C [QuartzCore+0x28f0] CA::Transaction::commit()+0x288 C [QuartzCore+0x1d7ab8] CA::Transaction::flush_as_runloop_observer(bool)+0x88 C [CoreFoundation+0x7cd80] __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+0x24 It seems it crashes in MTLLayer.m#blitCallback again in creating a new object jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer); [~jdv] Would you have some idea as to why it will fail there?
17-07-2024

Seems AWTWindow.m#_deliverMoveResizeEvent is called from windowDidMove, a NSWindowDelegate method called from OS and it crashes in creating a object from a weakreferenced object "javaplatformWindow" jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
17-07-2024

Crash dump shows C [libawt_lwawt.dylib+0xb538] -[AWTWindow _deliverMoveResizeEvent]+0xa4 C [CoreFoundation+0x9ab5c] __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__+0xc C [CoreFoundation+0x9aa4a] _CFXRegistrationPost+0x1ba C [CoreFoundation+0x9a792] ___CFXNotificationPost_block_invoke+0x32 C [CoreFoundation+0x58570] -[_CFXNotificationRegistrar find:object:observer:enumerator:]+0x680 C [CoreFoundation+0x576a3] _CFXNotificationPost+0x253 C [Foundation+0x6477] -[NSNotificationCenter postNotificationName:object:userInfo:]+0x42 C [AppKit+0x103693] -[NSWindow _setFrameCommon:display:stashSize:]+0xee5 C [AppKit+0x1027a1] -[NSWindow _setFrame:display:allowImplicitAnimation:stashSize:]+0xde C [AppKit+0x1026bc] -[NSWindow setFrame:display:]+0x43 C [libawt_lwawt.dylib+0xdf51] __Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds_block_invoke_1+0x11c C [JavaNativeFoundation+0x6f4a] +[JNFRunLoop _performCopiedBlock:]+0x11 C [Foundation+0x68985] __NSThreadPerformPerform+0x14e C [CoreFoundation+0xa36c1] __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11 C [CoreFoundation+0x15d2cc] __CFRunLoopDoSource0+0x6c C [CoreFoundation+0x86160] __CFRunLoopDoSources0+0xd0 C [CoreFoundation+0x855dd] __CFRunLoopRun+0x50d C [CoreFoundation+0x84e43] CFRunLoopRunSpecific+0x1e3 C [java+0x6465] CreateExecutionEnvironment+0x367 C [java+0x218c] JLI_Launch+0x7a0 C [java+0x84c2] main+0x65 C [java+0x19e4] start+0x34 ie in AWTWindow _deliverMoveResizeEvent] in AWTWindow.m SwingNode is not present in the dump, it's not very evident from where the resize event is coming..
16-07-2024