I was tasked to update a project with Maven 3.0 / Java 8 to Maven 3.6 / Java 12. To my best knowledge I did just that, changing all kinds of dependencies. Now when running the build the integration-test phase seems to be missing.
For example, the following plug-in is not called any longer during clean verify:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>do-magic</id>
<phase>pre-integration-test</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- ... -->
</configuration>
</plugin>
I can easily search the build log for do-magic, so I can confirm it's called in Java 8 but not in Java 12 (even though there might be some other changes I'm not aware of right now).
The debug output is:
[DEBUG] Goal: com.google.code.maven-replacer-plugin:maven-replacer-plugin:1.4.1:replace (do-magic)
[DEBUG] Style: Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- same as above-->
</configuration>
So there is no information on why it is not executed.
I tried calling the goal integration-test manually, still the plug-in is not called. There is no additional information either.
I have no idea where to look for the source of the problem. I wouldn't even know where to disable integration tests like this (except for maybe maven.test.skip, which removes the test module from the reactor altogether, so it's not that).
Can anybody shed some light on this issue?
The problem isn't that the integration-test phase is skipped, it's that suddenly maven-surefire-plugin decided it wants to execute the tests as well. That fails, because the pre-integration-test phase is needed for the tests.
I have no idea why that suddenly happened, so here is a pseudo fix that disables Surefire again:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- We run integration tests with failsafe! -->
<skip>true</skip>
</configuration>
</plugin>
Related
I'm trying to run a maven build from command line and exclude PITest from running any mutations. Currently the reports are failing and we need to be able to give a parameter to ignore running the mutation tests or ignore the results and continue the build
I've running with some parameters like mvn package -Dpit.report=true
or mvn package -Dmaven.report.skip=true
This is the PITest setup in my pom
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.1.10</version>
<configuration>
<timestampedReports>false</timestampedReports>
<mutationThreshold>95</mutationThreshold>
</configuration>
<executions>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>mutationCoverage</goal>
</goals>
</execution>
</executions>
</plugin>
The problem is that is is still running PITest and causing the build to fail
There is no native way of skipping a plugin execution, but there are least 2 workarounds:
First, is adding a property to override execution phase:
Define a property pitPhase with default value as the default phase of plugin execution.
Then in plugin configuration:
<execution>
<phase>${pitPhase}</phase>
...
</execution>
After that, when you want to skip execution mvn -DskipPit=pitPhase package
The other alternative is to add a Maven profile with the plugin execution
The execution of Pitests can be skipped in Maven.
In your pom.xml:
Set in general properties:
<properties>
<pitest.execution.skip>true</pitest.execution.skip>
</properties>
Set in the plugin:
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>Your_Version</version>
<configuration>
<skip>${pitest.execution.skip}</skip>
</configuration>
</plugin>
Since 1.4.11 there is the option skipPitest. See here: https://github.com/hcoles/pitest/releases/tag/pitest-parent-1.4.11
So you do: -DskipPitest
I am using Apache Maven 3.3.9 with the Groovy Maven plugin. Here is the relevant section of the pom.xml (the inlined Groovy script is just fictional):
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>myGroovyPlugin</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
log.info('Test message: {}', 'Hello, World!')
</source>
</configuration>
</execution>
</executions>
</plugin>
If I am calling mvn install the inline Groovy script gets called by the plugin as part of the prepare-package phase and works just fine. But if I try to call the plugins' goal directly via mvn groovy:execute I get the following error message:
[ERROR] Failed to execute goal org.codehaus.gmaven:groovy-maven-plugin:2.0:execute (default-cli) on project exercise02: The parameters 'source' for goal org.codehaus.gmaven:groovy-maven-plugin:2.0:execute are missing or invalid -> [Help 1]
The error you are getting is already pointing at the issue: the plugin couldn't not find the source configuration option because indeed it is only configured within the myGroovyPlugin execution, that is, only in the execution scope and not as a global configuration.
This is the main difference between configuration element outside the executions (global configuration for all executions of the plugin (even from command line) and within an execution (configuration only applied to that particular goal execution).
To fix the issue you should move the configuration element outside the executions section in this case, since the plugin is not a plugin invoked during default bindings by Maven, it would be enough and not have impact on your build: it will be still used during the myGroovyPlugin execution AND from explicit executions from command line.
From Maven POM reference, the configuration within an execution:
confines the configuration to this specific list of goals, rather than all goals under the plugin.
To make it clear, you should change it to the following:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>myGroovyPlugin</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<source>log.info('Test message: {}', 'Hello, World!')</source>
</configuration>
</plugin>
As such the configuration will become a global configuration and applied to both command line executions and declared executions.
Since you are using Maven 3.3.9, you could also make use of a slightly more verbose pattern to invoke directly a specific configuration of an execution:
mvn groovy:execute#myGroovyPlugin
This pattern is useful in cases where you really don't want a global configuration because you don't want to impact other (often default) executions of a certain plugin and you really want to use a specific isolated configuration both in an execution and from command line.
For our end-2-end test we need to execute the following logical flow:
Create and set up e2e schema (user) in the database (pre-integration-test)
Run Liquibase to initially populate the schema (pre-integration-test)
Add e2e-specific test data to the DB tables (pre-integration-test)
Start Tomcat (pre-integration-test)
Run the web application in Tomcat (integration-test) using Protractor
Shut down Tomcat (post-integration-test)
Clean up the DB: drop the schema (post-integration-test)
For running SQL the sql-maven-plugin is used, however this flow doesn't fit the regular POM layout:
The SQL plugin has to run during pre-integration-test twice, before and after the liquibase-maven-plugin
The SQL plugin has to run before Tomcat plugin during pre-integration-test, however it has to run after during post-integration-test, so that the DB schema is dropped after Tomcat has shut down.
As far as I could conclude from Maven docs, the order of plugins in the POM defines the order of execution during the same phase, and a plugin cannot be mentioned twice in the same POM.
Question: Is there any way to achieve this, apart from writing a shell script that would invoke Maven multiple times?
P.S. found a similar unanswered question.
Given the sample POM below:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-project</artifactId>
<version>0.0.2-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>print-hello</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo message="hello there!" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>exec-echo</id>
<phase>validate</phase>
<configuration>
<executable>cmd</executable>
<arguments>
<argument>/C</argument>
<argument>echo</argument>
<argument>hello-from-exec</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>print-hello-2</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo message="hello there 2!" />
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
We are actually configuring:
The maven-antrun-plugin to print the hello there! message
The exec-maven-plugin to print the hello-from-exec message
The maven-antrun-plugin to print the hello there 2! message
Goal executions are all attached to the same phase, validate, and we would expect to be executed in the same defined order.
However, when invoking (the -q option is used to have exactly and only their output):
mvn validate -q
we would have as output:
main:
[echo] hello there!
main:
[echo] hello there 2!
hello-from-exec
That is, for the same phase, Maven executed the defined plugins, however merging all of the defined executions for the same plugins (even if defined as different plugin sections) and then execute them in the order to merged definitions.
Unfortunately, there is no mechanism to avoid this merging. The only options we have for configuring plugins execution behaviors are:
The inherited configuration entry:
true or false, whether or not this plugin configuration should apply to POMs which inherit from this one. Default value is true.
The combine.children and combine.self to
control how child POMs inherit configuration from parent POMs by adding attributes to the children of the configuration element.
None of these options would help us. In this case we would need a kind of merge attribute on the execution element or have a different behavior by default (that is, Maven should respect the definition order).
Invoking the single executions from command line as below:
mvn antrun:run#print-hello exec:exec#exec-echo antrun:run#print-hello-2 -q
We would instead have the desired output:
main:
[echo] hello there!
hello-from-exec
main:
[echo] hello there 2!
But in this case:
We are not attached to any phase
We are invoking directly specific executions (and their configurations) via command line (and via a new feature only available since Maven 3.3.1
You can achieve exactly the same via scripting or via exec-maven-plugin invoking maven itself, but - again - the same would apply: no phase applied, only sequence of executions.
Assume that I have a simple XML file:
<?xml version="1.0" encoding="UTF-8"?>
<root property="${my.custom.maven.property}"/>
Because my.custom.maven.property is obtained by Maven plugin, I can't modify its value and it is non-escaped UTF-8 String, so it may (and it does) contain a special characters like ". This would lead to error after packaging or compilation phases (mostly at deployed server...). I want to prevent that situation by XML validation.
The point here is I am using xml-maven-plugin:validate. That won't help, because I can't specify that this validation should be done after filtering (well, filtering here means injecting those Maven property value). Plugin config looks really simple:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
<configuration>
<validationSets>
<validationSet>
<dir>xml_root</dir>
<includes>
<include>**/*.xml</include>
</includes>
</validationSet>
</validationSets>
</configuration>
</plugin>
The Maven properties injection is handled by the Resources Plugin which has a bind by default to the process-resources phases, while the XML Maven Plugin validate goal has a default binding to the test phase, probably too late during your build.
You can move the XML validation earlier in the Maven lifecycle and apply it right after the properties injection binding it to the process-resources phase as well as following:
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
Note the additional phase element.
As such, Maven would inject and then validate the XML and your build will fail (if required) much earlier.
For a full list of phases and their order, check official Maven documentation here.
Beware: in case you would use it, some Eclipse (m2e) versions may not like a different phase binding, you can ignore this error as long as the command line build works fine (always trust the command line build).
I have a Java project in Eclipse, with JUnit tests in my src/test directory. I've also added a class to my tests with Caliper microbenchmarks, and I'd like to be able to run these tests from within Eclipse.
As the Caliper code is test code, I've added Caliper as a dependency in Maven in test scope. That makes it show up in the classpath when I run JUnit tests, but I can't see a way to run an arbitrary class with test dependencies in the classpath. What I tried doing was adding a new Run Configuration for a Java Application, thinking I could launch CaliperMain with the right class as a parameter, but the Caliper jar is not on the classpath and I can't see how to add it.
I don't want to move my benchmark code and dependency into the main scope, as it's test code! It seems seriously overkill to move it into a completely separate project.
You should be able to do this with the Maven Exec Plugin. For my project, I opted to make a benchmark profile that can be run with the maven command mvn compile -P benchmarks.
To configure something like this, you can add something along the lines of the following to your pom.xml, specifying scope of the classpath as test using the <classpathScope> tag:
<profiles>
<profile>
<id>benchmarks</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>caliper</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>com.google.caliper.runner.CaliperMain</mainClass>
<commandlineArgs>com.stackoverflow.BencharkClass,com.stackoverflow.AnotherBenchmark</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Alternatively, if you'd like to specify a lot of options for caliper, it is probably easier to use the <arguments> tags:
<executions>
<execution>
<id>caliper</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>com.google.caliper.runner.CaliperMain</mainClass>
<arguments>
<argument>com.stackoverflow.BencharkClass</argument>
<argument>--instrument</argument>
<argument>runtime</argument>
<argument>-Cinstrument.allocation.options.trackAllocations=false</argument>
</arguments>
</configuration>
</execution>
</executions>
More configuration options (like -Cinstrument.allocation.options.trackAllocations above) can be found here and more runtime options (like --instrument above) can be found here.
Then, if you are using the Eclipse m2 Maven plugin, you can right-click on your project folder and select Run as... -> Maven Build... and enter something like clean install in the Goals input box and benchmarks in the Profiles input box and click Run and you should see the output in your Eclipse console.
It's important to note that I used a local snapshot build of Caliper by checking out the source using git clone https://code.google.com/p/caliper/, which is recommended at the time of this post in order to take advantage of the latest API.