Assume we have maven multimodule project "Foo":
Foo
|-web-module-war
|-dependency-jar
There are two profiles defined for moduleC:
<profile>
<id>poll-some-external-service</id>
<properties>
<dependency-jar.poll.configured>true</dependency-jar.poll.configured>
</properties>
</profile>
<profile>
<id>produce-some-product</id>
<properties>
<dependency-jar.poll.configured>false</dependency-jar.poll.configured>
</properties>
</profile>
Now we run two builds:
mvn clean package -P poll-some-external-service
mvn clean package -P produce-some-product
First build produce following artifacts:
web-module-war-1.0.0-poll.war
dependency-jar-1.0.0-poll.war
Second build produce following artifacts:
web-module-war-1.0.0-produce.war
dependency-jar-1.0.0-produce.war
This means that war file contains web application which works in a different way based on selected profile.
Naming is based on the following configuration in the parent pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<jarName>${project.build.finalName}${foo.build.info}</jarName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>${project.build.finalName}${foo.build.info}</warName>
</configuration>
</plugin>
How can I deploy these artifacts into Nexus? -poll/-produce part is stripped during deployment. This means we have two different applications of the same version but we can deploy only one of them
Thanks
Instead of changing the name use a classifier
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<classifier>poll</classifier>
</configuration>
</plugin>
Your profile for the pom should look similar to the following example. Note that you have to change the dependencies by using the profile too.
<profile>
<id>poll</id>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<classifier>poll</classifier>
</configuration>
</plugin>
</plugins>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dependency-jar</artifactId>
<classifier>poll</classifier>
</dependency>
</dependencies>
</build>
</profile>
Related
I am trying to exclude some files from a Maven war build by using profiles, and just cannot figure out to get that done.
I have created two profiles in pom.xml, created an eclipse run configuration for each, and can invoke them separately. But the resultant builds both have all the files in the eclipse project, no matter what I try.
I have simplified it to A and B, profile A is the 'default' profile.
<profile>
<id>profile-a</id>
<build>
<finalName>builda</finalName>
<plugins>
<plugin>
<artifactId>cloud</artifactId>
<version>11.0.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<classifier>profile-a</classifier>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
And profile B is the one where I want to remove some files, and have tried all sorts of ways, and have reduced it to not including anything, and all the possible exclude methods are shown also.
<profile>
<id>profile-B</id>
<build>
<finalName>buildb</finalName>
<plugins>
<plugin>
<artifactId>cloud</artifactId>
<version>11.0.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<classifier>cloud-service</classifier>
<excludes>
<exclude>**/*.txt</exclude>
</excludes>
<packagingExcludes>**/*.txt</packagingExcludes>
<warSourceExcludes>**/*.txt</warSourceExcludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
But both builda.war and buildb.war are identical - I compared the war files with Beyond Compare, and the only difference is the timestamp in the Manifest. I also tried removing a .jar file just to see if it was something about .txt files, but no difference at all.
So I'm thinking that the build information is coming from my eclipse project not from pom.xml. Or I completely missing something - I am still a maven newbie, so that is entirely possible.
But how to get this done?
First of all I feel that I should point out that there seem to be multiple problems with the POM you've provided. I think you should take some time to read through the Maven POM Reference, Maven Build Lifecycle, and related documentation.
Based on what you provided I think you're trying to add a classifier to your artifact based on the profile that was active during the build. I preserved this functionality and corrected the other aspects of the POM as best I could, but I made a few assumptions.
Here is the modified 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>web.example</groupId>
<artifactId>exampleWar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>profile-a</id>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<classifier>profile-a</classifier>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>profile-b</id>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<classifier>profile-b</classifier>
<packagingExcludes>%regex[.*\.txt]</packagingExcludes>
<warSourceExcludes>%regex[.*\.txt]</warSourceExcludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
I have a multi module project having the following structure:
Project:
- module1
- module2
- integration-test
- parent pom
What is the correct way of achieving the following:
run unit tests from all modules(except integration-test) using mvn clean install
run integration tests on demand(may be by using maven-failsafe plugin or via a maven profile? )
fail the build when integration tests fail.
By Default integration tests should not be run using mvn clean install
integration-test module has only the integration tests.
I have tried multiple hacks using maven-failsafe plugin and maven-sunfire-plugin(for unit tests) but not able to achieve the above in standard way.
Following is how the relevant portion of integration-test pom looks like:
<dependencies>
<!-- dependencies required for this module-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>add-integration-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-integration-test-resources</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/test/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>run-its</id>
<build>
<plugins>
<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>
</profile>
</profiles>
currently when i run mvn clean install it runs integration tests too. When i run mvn -Prun-its clean verify, it is running unit tests from other modules too. what am i missing?
You can skip execution of the Integration tests simply by setting -DskipITs=true when running your build like so:
mvn clean install -DskipITs=true
this will run all other tests but your ITs (see here for doc).
If you only want to run
mvn clean install
you can set the default for skipITs in your pom.xml
<properties>
<skipITs>true</skipITs>
</properties>
This way you can override it on demand with
mvn clean install -DskipITs=false
To run only ITs without Unittests you can configure the -Property of the maven-surefire-plugin like so
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skip>${skipUnitTests}</skip>
</configuration>
</plugin>
so if you run
mvn clean install -DskipITs=false -DskipUnitTests=true
Note that skipUnitTests will be false by default so no need to declare a property for that.
If you'd rather use a Profile it should work like that
<profile>
<id>ITs</id>
<properties>
<skipUnitTests>true</skipUnitTests>
<skipITs>false</skipITs>
</properties>
</profile>
and run the build like so
mvn clean install -PITs
Of course you could also use the plugin-configuration for maven-surefire-plugin with true directly in the profile so there'd be no need for the extra property, like
<profile>
<id>ITs</id>
<properties>
<skipITs>false</skipITs>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
I don't know if that's the best solution but you can achieve that using profiles. For example in the main pom.xml you add just the other modules in the <modules> section and then add another profile:
<modules>
... standard modules ...
</modules>
<profiles>
<profile>
<id>tests</id>
<modules>
<module>module1</module>
... standard modules repeated (it might not be needed>...
<module>module2</module>
<module>module-integration-test</module>
</modules>
</profile>
</profiles>
Then you run maven with that profile if you wnat to run tests.
maven -P tests clean install
That would work if you want to run integration tests AND the other modules. If you want to run just the integration tests you can do it like that:
<modules>
<!-- EMPTY -->
</modules>
<profiles>
<profile>
<id>defaultModule</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>module1</module>
... standard modules repeated (it might not be needed>...
<module>module2</module>
</modules>
</profile>
<profile>
<id>tests</id>
<modules>
<module>module-integration-test</module>
</modules>
</profile>
</profiles>
This way with mvn clean install you will run with defaultModule (which is activeByDefault) and if you specify -P tests you will run just tests
The best is to make a separate module which contains the integration tests which looks like already shown in your own question. Now how to handle the integration tests being running or not ...
The integration-test module looks like this:
<?xml version="1.0"?>
<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>
<parent>
<groupId>groupOfYourParant</groupId>
<artifactId>integration-test</artifactId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>integration-test</artifactId>
<packaging>jar</packaging>
<name>Mod-IT</name>
<dependencies>
<dependency>
<groupId>groupId</groupId>
<artifactId>TheArtifact</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Supplemental deps only needed in this module -->
<dependency>
<groupId>....</groupId>
<artifactId>....</artifactId>
<version>...</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>run-its</id>
<build>
<plugins>
<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>
</profile>
</profiles>
</project>
By using this you can simply control to run the integration tests via:
mvn -Prun-its clean verify
It's important that you have define the dependencies to other modules which are needed by the integration tests module or where it made be sure that those modules have to be built before this integration test module.
Furthermore you can now configure here supplemental things which are needed for integration tests and which should be run for example in the pre-integration-test and/or in post-integration-test phase.
If you put the test code into src/test/java plus optional resources into src/test/resources you can now define dependencies within your integration test module separately from any other module.
You should of course define the versions for your plugins in a pluginManagement in your parent pom to define all plugins which are being used during a build.
I finally got my test automation running using JUnit4 #Category for each test; they are marked as either PriorityHigh, PriorityMedium, or PriorityLow.
In my pom.xml I have each set up as a profile:
<profile>
<id>PriorityHigh</id>
<properties>
<testcase.category>com.categories.PriorityHigh</testcase.category>
</properties>
</profile>
<profile>
<id>PriorityMedium</id>
<properties>
<testcase.category>com.categories.PriorityMedium</testcase.category>
</properties>
</profile>
<profile>
<id>PriorityLow</id>
<properties>
<testcase.category>com.categories.PriorityLow</testcase.category>
</properties>
</profile>
Which is then used in the plugin section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<configuration>
<groups>${testcase.category}</groups>
<systemPropertyVariables>
<automation.driver>${browser.name}</automation.driver>
</systemPropertyVariables>
</configuration>
</plugin>
My issue is when I want to test both Medium and High, I specify
-P PriorityHigh,PriorityMedium
But instead of adding/concatenating, they overwrite and so only Medium tests run. To add extra difficulty, since pom.xml complains that ${testcase.category} only exists in profiles, and no default, I had to add this:
<testcase.category>com.categories.PriorityHigh,com.categories.PriorityMedium,com.categories.PriorityLow</testcase.category>
in case no profile is specified.
So two questions:
How to get the profiles to stack correctly in the "groups" node?
A better way to work it if no profile is specified (all tests should run)?
The easiest thing to do would be to ditch profiles and just use system properties:
<properties>
<testcase.category>com.categories.PriorityHigh,com.categories.PriorityLow</testcase.category>
</properties>
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<groups>${testcase.category}</groups>
...
</configuration>
</plugin>
Then:
mvn verify -Dtestcase.category=com.categories.PriorityHigh
# runs PriorityHigh tests
mvn verify -Dtestcase.category=com.categories.PriorityHigh,com.categories.PriorityLow
# runs PriorityHigh and PriorityLow tests
mvn verify
# runs PriorityHigh and PriorityLow tests
If you don't want to have to specify the fully qualified category class name on the Maven command line, you could use the Build Helper plugin to qualify the names for you:
<properties>
<testcase.category>PriorityHigh,PriorityLow</testcase.category>
</properties>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>build-fq-testcase-category</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>fq.testcase.category</name>
<regex>([^,]+)</regex>
<value>${testcase.category}</value>
<replacement>com.categories.$1</replacement>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<groups>${fq.testcase.category}</groups>
</configuration>
</plugin>
Then:
mvn verify -Dtestcase.category=PriorityHigh
# just run PriorityHigh tests
mvn verify
# run PriorityLow and PriorityHigh tests
# etc.
I have a Maven project and I have two profiles (Dev and integraiton). I use integration-profile to call two plugins, WAR and EAR maven plugin.
My question : how can I use the plugin in the pom.xml dependencies when integration-profile is set in the Maven goal (I don't Like to have a plugins call in the profile)?
<profiles>
<profile>
<id>integration-profile</id>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/jboss-web.xml</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<packagingExcludes>conf/jboss-roles-mapping.conf</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
I have next question:
I use liquibase maven plugin and by default when i making mvn clean package it dropAll tables and updates them.
<code>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.3</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
</plugin>
</code>
But, i want to turn off execution of this plugin for all maven phases, i need it only when i am executing mvn liquibase:dropAll or mvn liquibase:update. How i can do it?
You can always place the plugin inside a profile. So it won't run unless you activate the profile:
<profiles>
<profile>
<id>liquibase</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.3</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
which you activate as follows:
mvn liquibase:update -Pliquibase