7

I am running multiple JUnit tests in parallel classes using Maven. I have clean up tasks that need to happen after all JUnit tests run. To handle this clean up, I am adding a shut down hook to a few tests. The shut down hook correctly executes when I am not running parallel, but I don't see the output (see example) from the shut down hook when I run parallel. Is there something I am doing wrong? Does the JVM exit using System.exit when executing in JUnit tests in parallel?

According to the Surfire documentation documentation, the parallel threads are executed in the same process, so I would expect Runtime.getRuntime to be the same process even if it is called between different tests and threads. Maven Surfire Plugin - Fork Options and Parallel Test Execution

The important thing to remember with the parallel option is: the concurrency happens within the same JVM process. That is efficient in terms of memory and execution time, but you may be more vulnerable towards race conditions or other unexpected and hard to reproduce behavior.

Here is an example from my unit test:

@Test
public void test()
{
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
        @Override
        public void run()
        {
            System.out.println("Test clean up triggered");
        }
    });
}

Here is the relevant portion of my pom:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        <parallel>classes</parallel>
        <threadCount>10</threadCount>
    </configuration>
</plugin>

Edited: The problem is fixed when I add my shut down hook in the @BeforeClass method. When I add it in the @Test method, I have the problem. I would like to be able to add the hook at any time.

JeredM
  • 897
  • 1
  • 14
  • 25

1 Answers1

0

Your shutdown Hooks are actually called, the issue I believe comes from the system.out.println call associated to your shutdown hooks with maven.

Testing directly with Eclipse, I have the output:

Test clean up triggered

And trying a slightly different version of your test:

    @Test
    public void test()
    {
        System.out.println("Testing");
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                try {
                                Files.createFile(Paths.get("test1"));
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
            }
        });

        assertTrue(true);   
    }

I can see at the root of my director the file "test1" created after calling mvn clean test

Tests made with:

  • openjdk version "1.8.0_121"
  • Junit 4.12
  • Maven 3.3.9
  • Maven surefire-plugin 2.17
Adonis
  • 4,670
  • 3
  • 37
  • 57
  • The key to my problem was running tests in Maven, in parallel, and with the shutdown hook set in @BeforeClass. When I was replicating the problem it was part of a larger project. I just built a quick 2 test project and the problem didn't reproduce. I don't know if this still reproduces as the problem was a while back I can't be sure if a bug fix was performed or if there was something else in my larger project creating the problem. – JeredM May 04 '17 at 16:57
  • 1
    @JeredM The example above is simply for a demonstration purpose. It is indeed more wise to make the initialization of a shutdown hook in a `@BeforeClass` method. Now, with the settings I listed above, I tried various combinations, the only failures I encountered were due to unordered tests (trying to remove the hook before it was declared, error which was expected). Out of curiosity, do you still have the setup you were using with this failure? – Adonis May 05 '17 at 12:43
  • I don't have that setup anymore :( – JeredM May 05 '17 at 14:02