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

Jonathan Gibbons jonathan.gibbons at oracle.com
Mon Mar 8 17:26:41 UTC 2021


Thanks for the update.

-- Jon

On 3/8/21 8:58 AM, Jaikiran Pai wrote:
> 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