Skip to content
 
 

Latest commit

 

History

116 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

process-exec-maven-plugin

forked from chonton/process-exec-maven-plugin

Improve end-to-end integration testing with maven. Process Executor Plugin allows you to to start multiple processes in pre-integration-test phase in order, and then stops all the processes in post-integration-test phase, in reverse order.

Since version 2.0.0, the plugin requires Java 9 or higher.

Goals

  • start - Pre-Integration-test phase. Starts a given process in the pre-integration-test phase. Requires one execution per process.
  • stop-all - Post-Integration-test phase. Stops all processes that are started in the pre-integration-test phase, in reverse order. Requires only one execution for all processes.

Arguments

  • arguments: Command line arguments as you would provide when starting a process in your terminal. So, for example to run something like this
   java -jar drop-wizard-app.jar server config.yaml

set arguments as:

  <arguments>
    <argument>${java.home}/bin/java</argument>
    <argument>-jar</argument>
    <argument>drop-wizard-app.jar</argument>
    <argument>server</argument>
    <argument>config.yaml</argument>
  </arguments>
  • executable: An optional argument to define the executable to call. If not set, the first argument will be the executable. The plugin will check if the executable exists. If not, and if the given executable is a relative path, the plugin will try to create an absolute path using the working directory. If this file does not exist, too, the executable argument will be used as-is. If it does exist, the absolute path will be used.
  • environment: Environment variables for the process
  <environment>
    <TERM>vt100</TERM>
  </environment>
  • name: Give a name to the process to start.
  • workingDir: Give a working directory for your process to start in. Could be same as name. If not provided, the build directory is used.
  • waitForInterrupt: Optional. Setting this value to true will pause your build after starting every process to give you a chance to manually play with your system. Default is false.
  • waitForProcessExit: Optional. Setting this value to true will make the start goal block until the started process exits on its own. If the process exits with a non-zero code, the build fails. Default is false.
  • waitForProcessExitTimeout: Optional timeout in seconds used only when waitForProcessExit=true. 0 means wait without timeout. If the timeout is reached, the build fails. Default is 0.
  • healthCheckUrl: Recommended, but optional. You should provide a healthcheck url, so the plugin waits until the healthchecks are all green for your process. If not provided, the plugin waits for waitAfterLaunch seconds before moving on.
  • healthCheckValidateSsl: Optional. If healthCheckUrl is specified, and is an HTTPS URL, Java's default SSL TrustManager will be used by default. If you are using a self-signed certificate, this parameter can be set to false to use a TrustManager that doesn't validate the certification path.
  • waitAfterLaunch: Optional. This specifies the maximum time in seconds to wait after launching the process. If healthCheckUrl is specified, then it will move on as soon as the health checks pass. Default is 30 seconds.
  • processLogFile: Optional. Specifying a log file will redirect the process output to the specified file. Recommended as this will avoid cluttering your build's log with the log of external proccesses.
  • wsl: Optional. Setting this value to true will start (and later stop) this process inside WSL instead of natively on Windows. See WSL mode below for details and limitations. Default is false.

Killing processes on exit

Killing the maven process (using Ctrl+C or kill <pid> command) will stop all the processes started by the plugin. Each process registers its own JVM shutdown hook immediately upon startup, providing a safety net: even if an exception occurs during health checks or other post-startup steps (preventing the normal registration in stop-all), the process will still be cleaned up when the Maven JVM exits normally or on Ctrl+C/SIGINT. Known limitation: a hard kill of the Maven JVM (taskkill /F, OOM, crash) does not execute shutdown hooks — complete cleanup against force-kills would require OS-level monitoring inside WSL, which is out of scope.

HealthCheckUrl

The health check url can be any scheme natively supported by JRE.

WSL mode

Setting wsl to true for a process execution starts that process inside WSL (Windows Subsystem for Linux) instead of natively on Windows. This lets you run Linux binaries (e.g. a Java process built for Linux, or any executable only available under Linux) from a Maven build that itself runs on Windows. On any other system than Windows, the wsl parameter is ignored.

  • Requires the build to run on Windows with WSL installed and a default distro registered (wsl -e ... is used, so no -d <distro> selection is currently supported).
  • The executable/arguments are passed to WSL unchanged — no path or argument translation is performed, and the plugin's own Windows-filesystem-based executable lookup is skipped in WSL mode. Make sure the configured executable and arguments are valid inside the target WSL distro.
  • Environment variables configured via environment are only set on the Windows-side wsl.exe process and are not automatically passed into the Linux-side process. Use WSLENV if you need to forward specific variables.
  • workingDir relies on WSL's own automatic path translation for Windows-drive paths (e.g. C:\... <-> /mnt/c/...); this is standard WSL behavior, not something the plugin implements.
  • On stop, the plugin sends SIGTERM to the real Linux-side process (found via a PID captured inside WSL at start time, not via the Windows-side wsl.exe wrapper process) and escalates to SIGKILL if the process hasn't exited within 30 seconds.
  • Requires a kill executable to be available in the target distro's PATH (true for common distros such as Ubuntu/Debian/Alpine).
  • <path-argument> for automatic path translation: Instead of <argument>, you can use <path-argument> to have path values automatically translated from Windows to WSL format. This is only active when wsl=true; when wsl=false, a <path-argument> is treated like a regular <argument> (only interpolated, no translation). Examples:
  <arguments>
    <argument>${java.home}/bin/java</argument>
    <argument>-jar</argument>
    <path-argument>${project.build.directory}/app.jar</path-argument>
    <path-argument>-Dloader.path=${project.build.directory}/services/libs-ecr</path-argument>
    <path-argument>-javaagent:${project.build.directory}/jacoco-agent.jar=destfile=${project.build.directory}/jacoco.exec</path-argument>
  </arguments>

The translator recognizes both plain path values and Windows paths embedded within flag values. Each path is detected by the pattern [A-Za-z]:\[/\\]... (drive letter + colon + path separator + content up to whitespace, comma, semicolon, or equals sign) and translated independently. Multiple embedded paths in a single value (e.g. -javaagent:jar=destfile=path or -Dloader.path=path1,path2) are all translated; the surrounding literal text (flags, separators) is preserved. Relative paths (e.g. config/settings.yaml) in plain path-arguments are resolved against workingDir before translation. The wslpath utility must be available in the target WSL distro's PATH (standard on all common distros). Known limitations: plain relative paths without a drive letter embedded within a flag value (e.g. -Dloader.path=services/libs-ecr without ${...}) are not recognized; paths with spaces within flag values may not be correctly detected.

POM example:

<build>
    <plugins>
        <plugin>
            <groupId>de.eitco.cicd.exec</groupId>
            <artifactId>process-exec-maven-plugin</artifactId>
            <version>1.0.0</version>
            <executions>
                <!--Start process 1, eg., a dropwizard app dependency-->
                <execution>
                    <id>switchboard-process</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
                        <name>Switchboard2</name>
                        <workingDir>switchboard2</workingDir>
                        <waitForInterrupt>false</waitForInterrupt>
                        <healthCheckUrl>http://localhost:8381/healthcheck</healthCheckUrl>
                        <arguments>
                            <argument>${java.home}/bin/java</argument>
                            <argument>-jar</argument>
                            <argument>${basedir}/../../app/target/switchboard-${project.version}.jar</argument>
                            <argument>server</argument>
                            <argument>${basedir}/bin/switchboard.yaml</argument>
                        </arguments>
                    </configuration>
                </execution>
                <!--Start process 2, eg., another dropwizard app dependency-->
                <execution>
                    <id>emodb-shovel-process</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
                        <name>emodb-shovel</name>
                        <workingDir>shovel</workingDir>
                        <waitForInterrupt>false</waitForInterrupt>
                        <healthCheckUrl>http://localhost:8181/healthcheck</healthCheckUrl>
                        <arguments>
                            <argument>${java.home}/bin/java</argument>
                            <argument>-jar</argument>
                            <argument>${basedir}/../../app/target/emodb-shovel-app-${project.version}.jar</argument>
                            <argument>server</argument>
                            <argument>${basedir}/bin/config-local-dc.yaml</argument>
                        </arguments>
                    </configuration>
                </execution>
                <!--Stop all processes in reverse order-->
                <execution>
                    <id>stop-all</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>stop-all</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

About

Maven: start multiple processes in pre-integration-test phase in order.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages