Pass port number from docker-maven-plugin to spring property - spring

I'm developing Spring Data JPA project that targets a MySQL database, and I want to run end-to-end integration tests from Maven.
So far, I've configured io.fabric8.docker-maven-plugin to spin up a MySQL container during pre-integration-test phase. It will use a random available port, which I need to pass to my application.properties file.
I've tried Automatic property expansion using Maven but I suspect that the mysql.port maven property is only getting resolved after the spring properties are getting updated.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>pass-port-number-from-docker-maven-plugin-to-spring-property</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- other jpa dependencies ... -->
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>docker-test</id>
<properties>
<docker-maven.version>0.21.0</docker-maven.version>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>mysql.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven.version}</version>
<configuration>
<images>
<image>
<alias>mysql</alias>
<name>mysql:5.7</name>
<run>
<env>
<MYSQL_ROOT_PASSWORD>my-secret-pw</MYSQL_ROOT_PASSWORD>
</env>
<ports>
<port>mysql.port:3306</port>
</ports>
<wait>
<log>ready for connections</log>
<!-- <time>20000</time> -->
</wait>
<log>
<prefix>mysql</prefix>
<date>ISO8601</date>
<color>blue</color>
</log>
</run>
</image>
</images>
</configuration>
<!-- Connect start/stop to pre- and
post-integration-test phase, respectively if you want to start
your docker containers during integration tests -->
<executions>
<execution>
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
application.properties
mysql.port = #mysql.port#
When I run my test I get a connection error, and when I inspect target/classes/application.properties I see that #mysql.port# hasn't been updated.
Any suggestions would be much appreciated.

# only works if you extend from spring-boot-starter-parent; you didn't show the relevant portions of your pom.xml. Assuming you did that, try attaching reserve-network-port to process-sources phase, before process-resources. It's very possible that when Maven copies the resources, the reserve-network-port hasn't ran yet.
What happens if you hardcode 3306 in application.properties?

Related

Unable to bind maven profile to spring boot profile

I've seen all the questions and post regarding this issue so please don't mark this as duplicate or route me to those issues, I have tried implementing those solutions but nothing worked as of now.
I have profile specific application.properties files i.e application-prod.properties, application-dev.properties, application-int.properties etc
pom.xml
<profiles>
<profile>
<id>prod</id>
<properties>
<activeProfile>prod</activeProfile>
</properties>
</profile>
<profile>
<id>int</id>
<properties>
<activeProfile>int</activeProfile>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<activeProfile>dev</activeProfile>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
…
</build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<mainClass>com.demo.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<executions>
<execution>
<id>show-profiles</id>
<phase>compile</phase>
<goals>
<goal>active-profiles</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
application.properties
spring.profiles.active=#activeProfile#
I'm doing mvn clean install -Pprod and then running the application.
I'm sure the maven profile is executing during the build as I get this during the build
The following profiles are active:
- prod (source: my-project-snapshot)
This is what I'm getting when running the application:
: The following profiles are active: #activeProfile#
Can anyone please help me here.
UPDATE
when I close my IDE(STS) and do the maven build, it is working. Any info regarding this info would be really appreciated.
Have you enabled resource filtering in your pom.xml? Since you are using spring-boot this can be easily enabled, in your pom.xml
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
…
</build>
UPDATE
I have put all your plugins in a sample project's pom.xml also matching your spring-boot version:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<profiles>
<profile>
<id>prod</id>
<properties>
<activeProfile>prod</activeProfile>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<activeProfile>dev</activeProfile>
</properties>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<executions>
<execution>
<id>show-profiles</id>
<phase>compile</phase>
<goals>
<goal>active-profiles</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<mainClass>com.example.demo.DemoApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
When I run
mvn clean package spring-boot:run -Pdev -DskipTests
I see in the log files
com.example.demo.DemoApplication : The following profiles are active: dev
And when I check the generated jar in target dir...target\demo-0.0.1-SNAPSHOT.jar\BOOT-INF\classes\ filtering has succeeded since in application.properties I get the line:
spring.profiles.active=dev
which in the source application.properties is
spring.profiles.active=#activeProfile#
So if you have a pom file similar to the above filtering should work.
Thanks a lot #pleft, I tried everything and because of that I realized this may not be a maven issue but an IDE issue. I'm using STS 3 and I found out that disabling "Refresh using native hooks" under Window > preferences > General > Workspace > Refresh using native hooks would solve the issue of STS IDE ignoring -P<profile> during maven build when STS is open.
There seems to be already a bug ticket for this.

Error in NonGUIDriver java.lang.IllegalArgumentException

I am trying to run a jmeter script using 'mvn verify' and getting below error. I am new to Jmeter and tried out solutions from previous post but in vain. How to resolve this?
[INFO] Error in NonGUIDriver java.lang.IllegalArgumentException: Problem loading XML <>, missing class com.thoughtworks.xstream.converters.ConversionException:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dap-Jmeter</groupId>
<artifactId>Jmeter</artifactId>
<version>1</version>
<packaging>jar</packaging>
<name>jmeter-maven</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>1.App</start-class>
<java.version>1.8</java.version>
<msgpack.version>0.7.0-p3</msgpack.version>
<lombok.version>1.14.8</lombok.version>
<rest.assured.version>2.3.3</rest.assured.version>
</properties>
<dependencies>
<dependency>
<groupId>kg.apc</groupId>
<artifactId>jmeter-plugins-standard</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>kg.apc</groupId>
<artifactId>jmeter-plugins-extras-libs</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<!-- Run JMeter tests -->
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
<!-- Fail build on errors in test -->
</executions>
<configuration>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins:pom:1.3.1</artifact>
</jmeterExtensions>
</configuration>
</plugin>
</plugins>
</build>
</project>
Check target/jmeter/logs folder, it should have full log file for your test(s), my expectation is that your test relies on a plugin or a third-party .jar file which is missing in the JMeter Classpath, if you need all this stuff like RestAssured and Lombok in your test you need to add them a little bit differently to wit
<configuration>
<testPlanLibraries>
<artifact>org.msgpack:msgpack-core:0.7.0-p3</artifact>
<articact>org.projectlombok:lombok:1.14.8</articact>
<artifact>com.jayway.restassured:rest-assured:2.3.3</artifact>
</testPlanLibraries>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins:pom:1.3.1</artifact>
<articact>kg.apc:jmeter-plugins-standard:1.4.0</articact>
</jmeterExtensions>
<downloadExtensionDependencies>false</downloadExtensionDependencies>
</configuration>
Full pom.xml just in case:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>com.example.jmeter</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<!-- Run JMeter tests -->
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
<!-- Fail build on errors in test -->
<execution>
<id>jmeter-check-results</id>
<goals>
<goal>results</goal>
</goals>
</execution>
</executions>
<configuration>
<testPlanLibraries>
<artifact>org.msgpack:msgpack-core:0.7.0-p3</artifact>
<articact>org.projectlombok:lombok:1.14.8</articact>
<artifact>com.jayway.restassured:rest-assured:2.3.3</artifact>
</testPlanLibraries>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins:pom:1.3.1</artifact>
<articact>kg.apc:jmeter-plugins-standard:1.4.0</articact>
</jmeterExtensions>
<downloadExtensionDependencies>false</downloadExtensionDependencies>
</configuration>
</plugin>
</plugins>
</build>
</project>
References:
Adding jar's to the /lib directory
Adding jar's to the /lib/ext directory
JMeter Maven Plugin Wiki
Five Ways To Launch a JMeter Test without Using the JMeter GUI
The below POM solved the issue.
<dependencies>
<dependency>
<groupId>kg.apc</groupId>
<artifactId>jmeter-plugins-extras-libs</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins-casutg:2.4</artifact>
<artifactId>kg.apc:jmeter-plugins-extras-libs:1.3.1</artifactId>
</jmeterExtensions>
<!-- The plugin uses some broken dependencies
An alternative is to set this to true and use excludedArtifacts, see below
-->
<downloadExtensionDependencies>false</downloadExtensionDependencies>
</configuration>
</plugin>
</plugins>
</build>

How to run maven test with mysql running in docker

I have a maven java project. I need to run a mysql docker image in maven test stage to run tests and when its done i can remove mysql docker image.
One example would be to use the Docker Maven Plugin (https://dmp.fabric8.io/). Here is an example pom that would start a MySQL container, do your integration tests using the Maven Failsafe Plugin, then stop the MySQL container. It also would pass the property mysql.jdbc.url to the tests so they have the right JDBC URL to the MySQL container running on the specific Docker host (which could be different depending how you are running Docker).
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.20.1</version>
<extensions>true</extensions>
<configuration>
<images>
<image>
<alias>database</alias>
<name>mysql:5.7</name>
<run>
<wait>
<log>mysqld: ready for connections</log>
<time>20000</time>
</wait>
<env>
<MYSQL_ROOT_PASSWORD>abc123</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>testdb</MYSQL_DATABASE>
<MYSQL_USER>mysql</MYSQL_USER>
<MYSQL_PASSWORD>mysql</MYSQL_PASSWORD>
</env>
<ports>
<port>3306:3306</port>
</ports>
</run>
</image>
<image>
<name>mvndemo</name>
<build>
<from>java:8-jre</from>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>docker:start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>docker:stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<mysql.jdbc.url>jdbc:mysql://${docker.host.address}/testdb</mysql.jdbc.url>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
You can also opt for Testcontainers you will need to change the driver to a specific JDBC driver from testcontainer that will do the spinning up and spinning down of your required service. They also support other databases and versions. It is quite easy to do. You also get the option to startup and stop the container yourself from within a junit test if you need advanced stuff like initialization scripts.

Can't bind maven-remote-resources-plugin to both bundle and process goals

I use the maven-remote-resources-plugin to get some resources from an artifact and also need to bundle some resources for use in another project.
I bind the maven-remote-resources-plugin to the bundle goal in the default section (not in a profile). And I bind the maven-remote-resources-plugin to the process goal in a profile.
My problem is that I don't get the shared resources when using the profile (I don't get the target\maven-shared-archive-resources folder).
If I remove the maven-remote-resources-plugin in the default section (the bundle binding) it works fine.
Any suggestions?
Below is my pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<dependencies>
<dependency>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
<resourcesDirectory>${basedir}/src/test/resources</resourcesDirectory>
<includes>
<include>**/*.sql</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>create-test-data</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
</testResource>
<testResource>
<directory>${project.build.directory}/maven-shared-archive-resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<configuration>
<resourceBundles>
<resourceBundle>com.mycompany.app:my-app-common:1.0-SNAPSHOT:test-jar</resourceBundle>
</resourceBundles>
<attachToMain>false</attachToMain>
</configuration>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
The problem was that the property outputDirectory is defined for both the process and bundle goals and I redefined it in the bundle goal.

Maven deploy multiple wars to embedded server for integration tests

I have had no issue running a maven war project on an embedded server for its own integration tests, but now I need to run multiple wars and test from a different project.
I would like to setup the following scenario...
I have two Maven war projects in my local workspace called War1 and War2. I would like to have a 3rd Maven project, WarIntegration, that contains only integration tests and does the following:
Packages War1
Packages War2
Starts an embedded server
Deploys both wars to same embedded server
Runs integration tests contained within WarIntegration (which will make http calls to War1 and War2)
Stops embedded server
Is this possible? What plugin setup will achieve this? What kind of project should WarIntergration be (packaging)? Should War1 and War2 be modules in WarIntegration or dependencies? Can all of the configuration be aded to the WarIntegration project or would it have to be spread across the projects?
This is similar to this question, except we must use an embedded server that is started and stopped by the project (probably when we run verify) and we need a separate project for integration tests:
I have a multi-module Maven 2 POM that has two WARs, how can I configure it to deploy both wars prior to running tests?
I was able to achieve this using the cargo-maven2-plugin.
Here are the relevant pieces of the pom for anyone who is interested...
...
<groupId>com.test</groupId>
<artifactId>webapp-integration</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
...
<dependency>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<version>1.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>webapp2</groupId>
<artifactId>com.test</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
<configuration>
<type>standalone</type>
<properties>
<cargo.servlet.port>8085</cargo.servlet.port>
</properties>
<deployables>
<deployable>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp/</pingURL>
<properties>
<context>testapp</context>
</properties>
</deployable>
<deployable>
<artifactId>webapp2</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp2/</pingURL>
<properties>
<context>testapp2</context>
</properties>
</deployable>
</deployables>
</configuration>
</configuration>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.12</version>
</dependency>
</dependencies>
<configuration>
<groups>com.test.integration.IntegrationTestMarker</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Watch out, the DEPLOYABLES element is a child of plugin/configuration, NOT plugin/configuration/configuration.
The example above should be :
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<container>...</container>
<configuration>
<type>standalone</type>
<properties>
<cargo.servlet.port>8085</cargo.servlet.port>
</properties>
</configuration>
<deployables>
<deployable>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp/</pingURL>
<properties>
<context>testapp</context>
</properties>
</deployable>
<deployable>
<artifactId>webapp2</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp2/</pingURL>
<properties>
<context>testapp2</context>
</properties>
</deployable>
</deployables>
</configuration>
</plugin>
</plugins>
Hope that helps !

Resources