Eugene Loy
Eugene Loy

Reputation: 12416

Integration testing with maven: run jar before tests and terminate after

I have a runnable jar that I want to run in a new process before my integration test start (on pre-integration-test) and get it terminated after my integration tests finish (on post-integration-test).

One of the things I could use is maven-antrun-plugin or exec-maven-plugin to start new process on pre-integration-test but how do I terminate it?

Maybe there is a better solution for what I am trying to achieve?

PS: I build my project both on Windows and Linux, so portability matters for me.

Upvotes: 9

Views: 8708

Answers (6)

Vlad Isajkin
Vlad Isajkin

Reputation: 361

For me it worked with exec goal from exec-maven-plugin and async setting.

 <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions>
      <execution>
        <id>Start your java process</id>
        <goals>
          <goal>exec</goal>
        </goals>
        <phase>pre-integration-test</phase>
      </execution>
    </executions>
    <configuration>
      <async>true</async>
      <executable>java</executable>
      <arguments>
        <argument>-classpath</argument>
        <classpath/><!-- classpath from the module dependencies-->
        <argument>your.MainClass</argument>
      </arguments>
      <environmentVariables>
        <somevariable>isSet</someVariable>
      </environmentVariables>
    </configuration>
</plugin>

The process gets automatically killed as soon as the maven run is over. You may also want to look at the asyncDestroyOnShutdown option

Upvotes: 2

SebastianX
SebastianX

Reputation: 209

Kill it by using call bash

 <!--Kill the started process.-->
          <target>
            <exec executable="bash"
                  dir="${project.build.directory}"
                  spawn="false">
              <arg value="-c"/>
              <arg value="ps ax | grep -i '${project.artifactId}' | awk 'NR==1{print $1}' | xargs kill -SIGTERM"/>
            </exec>
          </target>

Upvotes: 0

nishant
nishant

Reputation: 985

I have solved this using maven-antrun-plugin.

If your background process is java process you can use the java ant target and give it a stop timeout. If you know that your integration tests will get over say after N seconds, fork & spawn the process and stop the process after a timeout (N)

        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.6</version>
            <executions>
                <execution>
                    <id>start-my-Application</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target>
                            <java jar="target/myapp-${project.version}.jar"
                                  spawn="true"
                                  fork="true"
                                  timeout="120">
                                <sysproperty key="env" value="test" />
                                <arg value="--xyz" /> <arg value="123" />
                            </java>
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Upvotes: 1

l8Again
l8Again

Reputation: 263

You can use maven-process-plugin open sourced by BV to start and stop any process in pre and post-integration phase respectively. There is an example in the readme that does exactly what you want (start a runnable jar). Hope that helps.

The main idea is to write a maven plugin with two goals - start, and stop. Start runs in your pre-integration-phase and runs any process you would like to run. Java's process builder can be used to start processes like running jars, etc. Store the started Process in a datastructure such as a Map or a Stack. 'Stop' will stop all the processes it has started. Since this is such a generic problem, I would recommend the above plugin for starting and stopping any processes easily for your integration tests. Simply add the following plugin:

<plugin>
        <groupId>com.bazaarvoice.maven.plugins</groupId>
        <artifactId>process-exec-maven-plugin</artifactId>
        <version>0.4</version>
        <executions>
            <!--Start process-->
            <execution>
                <id>start-jar</id>
                <phase>pre-integration-test</phase>
                <goals><goal>start</goal></goals>
                <configuration>
                    <workingDir>app</workingDir>
                    <arguments>
                        <argument>java</argument>
                        <argument>-jar</argument>
                        <argument>app.jar</argument>
                    </arguments>
                </configuration>
            </execution>
            <!--Stop Process-->
            <execution>
                <id>stop-jar-process</id>
                <phase>post-integration-test</phase>
                <goals><goal>stop-all</goal></goals>
            </execution>
        </executions>
</plugin>

Upvotes: 10

blackbuild
blackbuild

Reputation: 5174

The easiest way is to include some kind of stop mechanism in your external jar (compare to the stop port of tomcat).

That way you would not need to handle PIDs or anything.

The easiest, and most resource saving way would be to simply open a server socket on a predefined (overridable) port.

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328594

If this was Linux only, I'd write the PID to a file and then just kill the process using this PID later.

My guess is that you can achieve something similar on Windows but you'd need a couple of non-standard tools.

The alternative is to open a socket in the new process and listen for a kill command on this socket. That works on all platforms but you need to modify the JAR.

Note: If you need to run several the integration tests in parallel, this will also cause problems.

Upvotes: 0

Related Questions