From b6bbee7f8c58cf02b00c90f5849fff7ec7153106 Mon Sep 17 00:00:00 2001 From: Project516 <138796702+Project516@users.noreply.github.com> Date: Thu, 5 Nov 2026 11:17:53 -0600 Subject: [PATCH] Terminate main before waiting for non-daemon threads. --- src/jvm.ts | 3 ++- test/java/MainThreadExit.java | 15 +++++++++++++++ test/jtreg/passing.txt | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/java/MainThreadExit.java diff --git a/src/jvm.ts b/src/jvm.ts index 589c381..fb01ec6 100644 --- a/src/jvm.ts +++ b/src/jvm.ts @@ -1360,6 +1360,8 @@ export class JVM { // nothing left to report to } } + // Main must be joinable before DestroyJavaVM waits for other threads. + yield* this.exitThread(t); // DestroyJavaVM: wait for the other non-daemon threads, then shut down. while (this.nonDaemonAlive(t)) { yield t.block(new Promise((r) => { @@ -1367,7 +1369,6 @@ export class JVM { check(); })); } - yield* this.exitThread(t); yield t.call(boot("java/lang/Shutdown").methodMap.get("shutdown()V")!); this.halt(code); } diff --git a/test/java/MainThreadExit.java b/test/java/MainThreadExit.java new file mode 100644 index 0000000..d7ae3ab --- /dev/null +++ b/test/java/MainThreadExit.java @@ -0,0 +1,15 @@ +public class MainThreadExit { + public static void main(String[] args) { + Thread main = Thread.currentThread(); + main.setUncaughtExceptionHandler((thread, error) -> System.out.println("uncaught: " + error.getMessage())); + new Thread(() -> { + try { + main.join(); + System.out.println("main alive: " + main.isAlive()); + } catch (InterruptedException e) { + throw new AssertionError(e); + } + }).start(); + throw new RuntimeException("main failed"); + } +} diff --git a/test/jtreg/passing.txt b/test/jtreg/passing.txt index 1266d2a..91bfd46 100644 --- a/test/jtreg/passing.txt +++ b/test/jtreg/passing.txt @@ -1053,6 +1053,7 @@ java/lang/Thread/SleepSanity.java java/lang/Thread/SleepWithDuration.java java/lang/Thread/ThreadStateTest.java java/lang/Thread/ThreadStopTest.java +java/lang/Thread/UncaughtExceptionsTest.java java/lang/Thread/virtual/Collectable.java java/lang/Thread/virtual/Locking.java java/lang/Thread/virtual/Reflection.java