Maven Plugin Surefire no accepting outputDirectory - maven

In Maven pom tried to have a single profile only for tests and their reports. Also all test related reports should end up in a single folder per project.
Acording to the documentation this should do the trick
<profiles>
<profile>
<id>integration</id>
<activation>
<property>
<name>integration</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<excludes>
<exclude>**/*$*</exclude>
<exclude>**/*_closure*</exclude>
<exclude>**/support/**</exclude>
</excludes>
<outputDirectory>${basedir}/target/reports</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Still all reports end up in ..\target\surefire-reports. Any idea why the ouputDirectory settings doesn't work

According to the documentation you have to use the reportsDirectory instead of outputDirectory which does not exist.

Related

Maven surefire tests - includes and excludes

I have a class A.java and two test classes, ATest.java and AITests.java. The ITest is for integration. The tests must be performed as:
When no Maven profile is selected only the Atest must be tested.
When the itests profile is activated the both tests (ATest and AITest) must be tested.
The problems is, when I use the command
mvn -P itests test
then only the ATest is tested, without the AITest. But I have no idea what I am missing here. Any hint?
My pom.xml is:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<excludes>
<exclude>**/*ITest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>itests</id>
<activation>
<property>
<name>itests</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
For integration tests, please use the Maven failsafe plugin:
https://maven.apache.org/surefire/maven-failsafe-plugin/
You can skip it on the command line if you prefer.

Maven - skip plugin if property is empty/null

I want to obtain the following behavior: when I specify a value for the property "my.prop", I want the dependency and clean plugins to be executed. If a value is not specified for that property, I want them to be skipped.
I created "my.prop" like this:
<properties>
<my.prop></my.prop>
</properties>
Then I read that profile activation works only for system properties, so I deleted the above and used the surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<my.prop></my.prop>
</systemPropertyVariables>
</configuration>
</plugin>
I tried using profiles, like this:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<skipDependecyAndCleanPlugins>false</skipDependecyAndCleanPlugins>
</properties>
</profile>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>my.prop</name>
<value></value>
<!-- I also tried: <value>null</value> without success.-->
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
Later, for each plugin I do something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
....
</plugin>
But the plugins are still executed...
How can I determine Maven to skip the executions of the plugins when "my.prop" is empty/null?
The simplest solution would be to use the activation in the following form:
<profiles>
<profile>
<activation>
<property>
<name>debug</name>
</property>
</activation>
...
</profile>
</profiles>
The above means you can define any value for debug which means -Ddebug is enough.
An empty value can't be defined a pom file cause <value></value> is equivalent to <value/> which means the same as not defined.
Update:
I would suggest to use a profile and NOT a property. So you can simply define on command line mvn -Pxyz install or leave it.
You can use my.prop property in plugin's configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${my.prop}</skip>
</configuration>
....
</plugin>
Now when you execute:
mvn ... -Dmy.prop=true
then plugin will be skipped
You were very close. You can achieve what you described by using the !my.prop syntax in profile activation.
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>!my.prop</name>
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
According to Maven documentation, the skip-dependency-and-clean-plugins profile will be activated when the system property my.prop is not defined at all.
Here is a solution that directly addresses the OP's original request: the ability to skip a plugin's execution if a POM property (not a system property) my.prop is not defined. This solution relies on the Apache Maven Help Plugin. It is a kludge, but given Maven's paucity of expression prowess, this is about the best you're gonna get. At least it relies on a well-known, hopefully-maintained plugin, and should work 100% of the time. Oh, and it may make your head explode. Or make you cry. Or both. You've been warned.
First declare the latest version of the Maven Help Plugin in the <build><pluginManagement> section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
</plugin>
Then add this "secret sauce" in the <build><plugins> section, which will check to see if my.prop is defined:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>set-is-skip-true-or-prefixed</id>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>_${my.prop}</value>
<regex>_\$\{my.prop\}</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<id>set-is-skip</id>
<phase>initialize</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>${is-skip}</value>
<regex>_.*</regex>
<replacement>false</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
Now you have a POM property (not a system property) named is-skip, which you can use in any later phase to disable a plugin—provided that plugin has a <skip> or similar option taking a Boolean value. If my.prop is not defined at all, is-skip will be set to true; otherwise is-skip will be set to false.
<plugin>
<groupId>org.example</groupId>
<artifactId>foobar-plugin</artifactId>
<executions>
<execution>
<id>foo</id>
<phase>package</phase>
<goals>
<goal>foo</goal>
</goals>
<configuration>
<skip>${is-skip}</skip>
</configuration>
</execution>
</executions>
</plugin>
There is one caveat: don't define my.prop at all, even to the empty string, or this solution will consider it defined and set is-skip to false. Setting is-skip to true if my.prop is set but empty would require an additional regex evaluation clause above. For my use case I didn't need it, as an empty my.prop isn't valid and I didn't define my.prop at all in the parent POM.
I'll leave it to you to understand how it works (my head exploded already when I was writing it), but I'll be happy to answer any questions.
In step #2 above, be sure and put the two regex evaluations in different phases, such as validate and initialize as used here. The reason is because Maven gets confused if you mix in the same plugins in in the same phase a child POM, and may scramble the execution order. (See MNG-5987.) My kludge of a solution relies on the order of evaluation.

Maven 3 profile with extensions

My question had been addressed in this thread, but the explanation is not clear.
I have this build definition in one of my pom.xml files:
<build>
<finalName>${my.project}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.kuali.maven.wagons</groupId>
<artifactId>maven-s3-wagon</artifactId>
<version>1.1.19</version>
</extension>
</extensions>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/settings.properties</include>
</includes>
</resource>
</resources>
</build>
Notice that I'm using the maven-s3-wagon extension.
Next, I would like to have 2 different profiles, each with it's own settings, plugins and extensions but maven does not allow the extensions tag under a profile.
When I try using a profile:
<profiles>
<profile>
<id>local-build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<finalName>${my.project}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.kuali.maven.wagons</groupId>
<artifactId>maven-s3-wagon</artifactId>
<version>1.1.19</version>
</extension>
</extensions>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/settings.properties</include>
</includes>
</resource>
</resources>
</build>
</profile>
</profiles>
I get a an error in my pom:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'extensions'. One of '{"http://maven.apache.org/POM/4.0.0":defaultGoal, "http://maven.apache.org/POM/
4.0.0":resources, "http://maven.apache.org/POM/4.0.0":testResources, "http://maven.apache.org/POM/4.0.0":directory, "http://maven.apache.org/POM/4.0.0":filters, "http://
maven.apache.org/POM/4.0.0":pluginManagement}' is expected.
Question So using the extension tag means I can't use profiles? How can I use or change build extensions via profile?
Indeed, the official Maven POM reference is not clear about the possible usage of extensions as part of a Maven profile, since it states you can have a build element within it, but not what of the build section.
However, the official Maven model effectively filters and provides what of the build section you can actually use within a profile section. And indeed extensions is not there.
However, what are Maven extensions? Build/Lifecycle enhancement, but also (and essentially): a library added to the runtime classpath of the Maven build, which participates to the build, but it is not packaged with the final artifact.
Hence, in such a scenario (if you need to have extensions in profile or have a profile to change/add an extension) you could use the following trick:
Have an harmless extension as default extension of your build (where harmless means whatever library which could be part of your build classpath and essentially not affect it at all)
Have properties defining the GAV coordinates (GroupId, ArtifactId, Version) of this extension
Have a profile which overrides these properties with the desired (useful) extension
As an example, given the following sample POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<extension.groupId>junit</extension.groupId>
<extension.artifactId>junit</extension.artifactId>
<extension.version>4.11</extension.version>
</properties>
<build>
<extensions>
<extension>
<groupId>${extension.groupId}</groupId>
<artifactId>${extension.artifactId}</artifactId>
<version>${extension.version}</version>
</extension>
</extensions>
</build>
<profiles>
<profile>
<id>customize-extension</id>
<properties>
<extension.groupId>junit</extension.groupId>
<extension.artifactId>junit</extension.artifactId>
<extension.version>4.12</extension.version>
</properties>
</profile>
</profiles>
</project>
The default build (without the customize-extension profile activated), would use the default defined properties and as such add junit as build extension: this is harmless (although it may create conflicts with another junit version of your build, so make sure you use the same version of use an even more harmless library for that).
You can check Maven will pick it up by running a really first build phase, just to check information in our case, and enable the debug flag:
mvn initialize -X
And checking as part of the build log:
[DEBUG] Populating class realm extension>junit:junit:4.11
[DEBUG] Included: junit:junit:jar:4.11
Now let's use our trick: let's add (change) a build extension via profile:
mvn initialize -X -Pcustomize-extension
And as part of our build log we would have:
[DEBUG] Populating class realm extension>junit:junit:4.12
[DEBUG] Included: junit:junit:jar:4.12
Bingo. Maven picked up a different extension (in this case, a different version, the 4.12) and we succeeded on changing (or actually adding a meaningful) build extension via profile.
Just a crazy idea: use modules
Define a parent pom like this:
<groupId>org.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>use-pom1</id>
<modules>
<module>pom1</module>
</modules>
</profile>
<profile>
<id>use-pom2</id>
<modules>
<module>pom2</module>
</modules>
</profile>
</profiles>
Define the desired extensions on pom1 and pom2.
I think the solution is here http://maven.apache.org/guides/mini/guide-using-extensions.html
Define a build section where extensions are defined and then into the profile set the attribute true ( like in the second profile shown below )
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.9</version>
</extension>
</extensions>
</build>
<profiles>
<profile>
<id>create-default</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>build</name>
<value>full</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>create-core</id>
<activation>
<property>
<name>build</name>
<value>full</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<extensions>true</extensions>
<version>2.6</version>
<configuration>
<finalName>import-station-core-${project.version}</finalName>
</configuration>
<executions>
<execution>
<id>make-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

Maven profile not deploying to correct tomcat using maven-tomcat-plugin

So my Maven doesn't want to pickup the right profile, doesn't matter how I tell it:
mvn -Denv=dev tomcat7:deploy-only or mvn -P dev -Denv=dev tomcat7:deploy-only
I have two servers configured on my settings.xml and have my configuration below pointing to the correct ones.
Using mvn -X it seems that Maven is always picking up the last server in order it appears on the file, which means it's picking up the prod server.
Any clues anyone? Thank you!
Here's my <profiles>:
<profiles>
<profile>
<id>dev</id>
<activation>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<server>dev</server>
<url>http://localhost:8080/manager/text</url>
<username>tomcat</username>
<password>tomcat</password>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>prod</value>
</property>
<jdk>1.6</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<server>prod</server>
<url>http://remote/manager/text</url>
<username>usr</username>
<password>pwd</password>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You have an extra "activation" of <jdk>1.6</jdk> in your prod profile. Activations are an "or", not an "and". I'm guessing you're running maven with jdk6, and so prod is always active. Being the last one in the pom, its settings will win--a general rule in maven.

How to run the exec-maven-plugin if a system property id set in Maven 3.x?

I want to run the 'exec-maven-plugin' if a system property is set. How do I accomplish this in Maven 3.x?
For example, given:
mvn clean install -DrunTheExec="yes"
Then how can I implement this logic:
<!-- if $(runTheExec) == yes then run this plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
</plugin>
I was just about to add the same suggestion as Johnathon, but using the profile a little differently.
<profiles>
<profile>
<id>runTheExec</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
then to activate it:
mvn clean install -PrunTheExec
You'll need to define a profile in your pom, with the plugin defined inside of it. In your example, this would be:
<profiles>
<profile>
<activation>
<property>
<name>runTheExec</name>
<value>yes</value>
</property>
</activation>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
</plugin>
</plugins>
</profile>
</profiles>

Resources