jtreg main/othervm "completes" even when there's a non-daemon thread currently active?

Jaikiran Pai jai.forums2013 at gmail.com
Mon Mar 8 16:58:16 UTC 2021


Sorry, never mind. Just after I sent this mail, I went back to the jtreg 
FAQ and used a different search term this time to see if this has been 
explained there and indeed I see it now 
https://openjdk.java.net/jtreg/faq.html#what-happens-if-my-test-returns-when-there-are-still-threads-running.

Sorry about this.

-Jaikiran

On 08/03/21 10:21 pm, Jaikiran Pai wrote:
> Please consider this trivial Java program:
>
> public class FooTest {
>     public static void main(final String[] args) throws Exception {
>         Thread t = new Thread(new Task());
>         t.setName("Thread-A");
>         t.start();
>         System.out.println("Main done");
>     }
>
>     public static class Task implements Runnable {
>         @Override
>         public void run() {
>             // wait forever
>             System.out.println("Initiating a wait");
>             try {
>                 new java.util.concurrent.CountDownLatch(1).await();
>             } catch (Throwable t) {
>                 t.printStackTrace();
>             }
>         }
>     }
> }
>
>
> All it does is launches a (non-daemon) thread and the thread just 
> waits (forever). When you run this as a normal Java program, as 
> expected it waits forever, even after the "main" thread is completed, 
> due to the other non-daemon thread.
>
> Now let's consider the exact same program converted into a jtreg, by 
> adding just the javadoc annotations:
>
>
> /**
>  * @test
>  * @summary Test jtreg
>  * @run main/othervm FooTest
>  */
> public class FooTest {
>     public static void main(final String[] args) throws Exception {
>         Thread t = new Thread(new Task());
>         t.setName("Thread-A");
>         t.start();
>         System.out.println("Main done");
>     }
>
>     public static class Task implements Runnable {
>         @Override
>         public void run() {
>             // wait forever
>             System.out.println("Initiating a wait");
>             try {
>                 new java.util.concurrent.CountDownLatch(1).await();
>             } catch (Throwable t) {
>                 t.printStackTrace();
>             }
>         }
>     }
> }
>
> (no change to the code, just the jtreg annotations/markers have been 
> added).
>
>
> Now run this from within the JDK testsuite (for example), using jtreg:
>
> jtreg -jdk:build/macosx-x86_64-server-release/images/jdk 
> test/jdk/java/lang/FooTest.java
>
> This "passes" (immediately). i.e. the jtreg launched program/test 
> doesn't wait for the non-daemon thread to complete and instead just 
> exits successfully when the main thread is done. I have verified the 
> logs to make sure it indeed exits cleanly without errors or timeouts 
> and does the run the code in that test.
>
> Is this expected? I haven't found this mentioned in the user guide (as 
> far as I can see) and a quick glance in the jtreg source code (the 
> MainWrapper specifically) doesn't tell me how this change in behaviour 
> of the JVM exit semantics would be possible (since it ultimately uses 
> ProcessBuilder to launch the program).
>
> -Jaikiran
>
>
>


More information about the jtreg-use mailing list