Maven 3 goal ordering - maven

There are two goals bound to the test phase of default Maven lifecycle. The first goal (in the order of appearance in the pom.xml) is:
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>update</id>
<phase>test</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
and the second is:
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
During the test phase, the surefire plugin is executed first, which contradicts with the Maven 3 FIFO ordering of goals in the same phase. I verified that the goals have the same order in the effective pom. Is it possible that one of the plugins is overriding the default order? Why is the surefire plugin executed before the liquibase one?

You are right that Maven executes the goals in the order as they are defined in the POM but in this special case, you used the default-test identifier for the second execution, which has a special meaning.
I can't find any reference about this behaviour right now but changing your <id> to something else will restore the behaviour you expect.
However, for this special case again, changing the id will make the maven-surefire-plugin execute twice: it is already executed by default and adding an execution (with an id different than default-test) will add another instead of overriding the default one.

Related

How to run two Maven Mojos with different parameters

I wrote a Maven plugin with two Mojos. They are meant to be run in the command line, not attached to any phase of the build.
They happen to have different parameters, and I don't know how to specify them. So far I've managed to use two executions one for each one, but it looks clumsy in the command line.
This is the plugin declaration in my pom.xml:
<plugin>
<groupId>myplugin.tools.camera</groupId>
<artifactId>camera-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>exe1</id>
<configuration>
<snapshotfile>file1.shot</snapshotfile>
<dir>dev</dir>
</configuration>
<goals>
<goal>take-shot</goal>
</goals>
</execution>
<execution>
<id>exe2</id>
<configuration>
<time>12:34.56</time>
<dir>test</dir> <!-- same parameter, with different value -->
</configuration>
<goals>
<goal>show-shot</goal>
</goals>
</execution>
</executions>
</plugin>
It works, but to run each Mojo I need to run:
$ mvn camera:take-shot#exe1
$ mvn camera:show-shot#exe2
Would it be possible to get rid of those #exe1 and #exe2?
Now, there could be an advantage to these executions, if I wanted to create multiple different parameters to later pick which one to use. I hoped there could be a default execution, but don't know how to do that.

Maven : how to order multiple execution of a goal in the same phase in a specfic order

I want my "pre-integration-test" phase to be the following execution of goals, in this specfic order.
PHASE : pre-integration-test
get a spring boot jar (maven-dependency-plugin:copy)
get-a-port (build-helper-maven-plugin:reserve-network-port)
display-port (maven-antrun-plugin:run #1)
start-server (exec-maven-plugin)
wait-for startup (maven-antrun-plugin:run #2)
Is there any way to do this using Maven 3?
The problem that I am facing, is that "maven-antrun-plugin:run" 1 & 2 will always be run one after the other, because they are defined in the same plugin element :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>display-port</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>Displaying value of 'tomcat.http.port' property</echo>
<echo>[tomcat.http.port] ${tomcat.http.port}</echo>
</target>
</configuration>
</execution>
<execution>
<id>wait-for-startup</id>
<phase>pre-integration-test</phase>
<configuration>
<target>
<sleep seconds="10" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Right now, the only way I have found to do this is to duplicate the "maven-antrun-plugin:" plugin element in the pom file.
But this gets me a warning
'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration
For the scope of this question, I am not looking for a work-around, such as changing the plugin for the "display-port" or "wait-for startup", or changing the phase on of the goals.
I just want to understand if what I am trying to do is possible or not.
If multiple executions have the same phase, then the first one to be executed will be the built-in one (e.g. maven-compiler-plugin) whose id is default-something, then the other executions will take place in the order they appear in your pom file.

Maven maven-dependency-plugin copy-dependencies ignores outputDirectory

I'm try to use the maven-dependency-plugin's copy-dependencies goal.
I checked its official example with the snippet below.
My problem is: the dependencies are always copied to
target\dependency folder, even if I specify an <outputDirectory> node.
Here is the part of my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
<configuration>
<outputDirectory>${project.build.directory}/aaa</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</executions>
</plugin>
</plugins>
</build>
Question: What I'm doing wrong? Is it possible to declare the output directory outside of the project? For example: c:\temp ?
You configured an execution of the maven-dependency-plugin with a configuration only defined within its scope, hence it will only be picked up by the plugin during a mvn package invocation, that is, while performing the package phase and the plugin (executions) having a binding to it.
If you invoke the plugin from command line as following:
mvn dependency:copy-dependencies
It will indeed only use default values, since your configuration will be ignored.
In fact, the default value for the outputDirectory option is indeed:
Default: ${project.build.directory}/dependency
In maven, a plugin configuration can be defined as general configuration (outside of an execution section, applied to all executions and to command line invocations) or per execution (within an execution section, like in your case).
In your case, you probably want the configuration to be valid in both cases, so simply change your plugin section to the following:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<configuration>
<outputDirectory>${project.build.directory}/aaa</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: we moved up the configuration, from execution scope to plugin (global) scope.
Also note, in the configuration above we kept the execution, which means maven will always execute this plugin goal at each an every mvn package invocation. If you don't want this behavior and only expect to use the command line execution, then you can remove the executions section at all.
Since Maven 3.3.1 it's also possible (see the note at the very end of Using the executions Tag section):
Since Maven 3.3.1 this is not the case anymore as you can specify on the command line the execution id for direct plugin goal invocation.
to execute copy-dependencies execution directly not modifying your pom at all:
mvn dependency:copy-dependencies#copy-dependencies
Note that of the two copy-dependencies separated by #, the former refers to the plugin goal and the latter refers to the execution id. And general direct invocation of an execution is:
mvn <plugin-prefix>:<goal>#<execution>
See also accepted answer to almost the same question

Can maven sortpom plugin affect a project's build result?

Can the Maven Sortpom Plugin affect the result of a project's build ?
Is it possible to have a project build fail just because the sortpom plugin was added ?
Normally the order of the elements in a pom.xml file does not matter, so reordering elements should not affect the build.
But I know of two exceptions to this rule:
Maven reads dependencies according to the order in the pom-file when compiling. Rearranging that order may affect the compilation output.
If two plugins executes in the same phase, the order in pom-file will determine which plugin to execute first. Sorting the plugins may cause the compilation to fail if the result of one plugin is dependent on another.
The sortpom plugin does not sort either dependencies nor plugins by default. So I would say that the sortpom plugin should not affect the result of a projects build.
It can fail a build:
[ERROR] Failed to execute goal com.google.code.sortpom:maven-sortpom-plugin:2.3.0:sort (default) on project data-extractor: scm.team.company.corp: Unknown host scm.team-project.company.corp -> [Help 1]
The if the file isn't found due to network problems, even when running with -o
Yes.
For example, you use:
org.codehaus.mojo:build-helper-maven-plugin's reserve-network-port goal in phase pre-integration-test
org.apache.tomcat.maven:tomcat7-maven-plugin's run goal also in phase pre-integration-test
Now, sortpom:sort orders them around, and in maven-3, the order of the plugins are important. So if you configure a random port for tomcat through the portName feature of reserve-network-port, the system property won't be filled (at the point it is needed), as after the sort, the build-helper artifact is executed AFTER the run goal is invoked.
Example after a sorting:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>start-tomcat</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>true</fork>
</configuration>
</execution>
<!-- ... -->
</executions>
<configuration>
<fork>true</fork>
<port>${tomcat.http.port}</port><!-- Oops, not set (yet)! -->
</configuration>
</plugin>
<!-- ... -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper.version}</version>
<executions>
<execution>
<id>reserve-tomcat-port</id>
<phase>pre-integration-test</phase>
<goals>
<goal>reserve-network-port</goal>
</goals>
<configuration>
<portNames>
<portName>tomcat.http.port</portName><!-- Too late -->
</portNames>
</configuration>
</execution>
</executions>
</plugin>

PMD - How to exclude files from violation check

We're checking our code using the PMD 'check' goal that is bound to the 'verify' life cycle. (http://maven.apache.org/plugins/maven-pmd-plugin/examples/violationChecking.html)
For the 'pmd' goal you can add 'excludes' and 'excludeRoots' but not for the 'check' goal.
How does one exclude eg. generated sources directories?
You need to do the pmd:pmd first and afterwards do a pmd:check. You can configure that simply by using. Bind that to a particular lifecycle-phase which is before verify. For example into package or pre-integration-test phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<goals>
<goal>pmd</goal>
<goal>check</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
The check goals (check, cpd-check are exactly intended to fail a build if there are some violations. So you can define some exceptions for the pmd goal which folders should be included/excluded.

Resources