Is it possible to execute same life cycle of two maven plugin if one fails ?
Example:
Let's say I have below plugin configuration,
<plugins>
<plugin>
<groupId>smothing</groupId>
<artifactId>plugin-1</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>doSomthing</id>
<phase>test</phase>
//...//
</plugin>
<plugin>
<groupId>something</groupId>
<artifactId>plugin-2</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>doSomthingAgain</id>
<phase>test</phase>
//...
</plugin>
</plugins>
I would like to execute plugin-2 test phase even if the first plugin fails. I don't want to ignore or skip test cases.
I have below two plugin to be executed same phase even if one fails.
<groupId>com.thoughtworks.gauge.maven</groupId>
<artifactId>gauge-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
Basically, after the gauge tests I want to perform some cleanup activities through maven exec plugin. So is there any option for me to always execute maven exec plugin ? (No command line arguments, something which I am expecting in pom.xml )
I have seen these answers, but everything says to skip test cases.
How to run a maven goal when there is tests failures?
Maven reporting plugins do not execute if a unit test failure occurs
Any help much appreciated :)
If a plugin fails, it'll stop the execution of the lifecycle. So you shouldn't try to solve it by thinking of executing another plugin for some condition.
Based on your description the best approach seems to be writing an extension, see https://maven.apache.org/examples/maven-3-lifecycle-extensions.html . With https://maven.apache.org/ref/3.6.0/maven-core/apidocs/index.html?org/apache/maven/execution/AbstractExecutionListener.html you can see that you can do actions before or after any segment of the lifecycle, e.g. cleaning up after projectSucceeded+projectFailed
Related
We have a use-case where we want to do sonar analysis as part of site generation. That is whenever "mvn install site:site" is invoked, we want sonar:sonar to be invoked as well as part of that.
We tried following plugin configuration, but that doesn't work to execute sonar goal as part of site phase (we tried "pre-site" phase too but that did not work as well):
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.3.0.603</version>
<executions>
<execution>
<id>sonar-site</id>
<phase>site</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<build>
Just for experimenting, when we changed: <phase>site</phase> to <phase>post-integration-test</phase> in the above snippet, sonar goal started getting executed after IT execution.
Is there something wrong in compatibility between sonar-maven-plugin and maven-site-plugin. Will appreciate any input or alternate approach to resolve this.
You bound the SonarQube Maven plugin to a site phase, but you didn't execute that phase. You passed site:site which means execute a site goal of the maven-site-plugin.
You have to execute: mvn install site
The solution with post-integration-test works, because that stage is executed by install phase (more or less).
Read more about Maven Lifecycle Reference.
I can use Maven to compile and test a program
mvn compile
mvn test
Is there a lifecycle command to simply run the program, or generate a script which will run the program?
If you are asking this question, it means it's unclear to you what the Maven lifecycle really is.
There is no lifecycle command, only a build lifecycle, which is made up of different phases.
So to make it clear: there is a build lifecycle, which is made up of phases, which are made up of plugin goals.
When you are invoking Maven with
mvn compile
You are invoking a build phase. In Maven, there is a list of predefined ordered phases. When you invoke a phase, all of the phase before it are also invoked. Invoking a phase means that you are invoking all of the plugins that are bound to this phase. For the compile case, this means it will, among others, invoke the maven-compiler-plugin wich is bound to the compile phase by default.
So to answer your question strictly: no, there is no lifecycle command to do that.
However, you can configure a plugin in your POM, which will be bound to a certain phase, and invoke that phase. For that, you can refer to #manouti's answer which introduces the exec-maven-plugin.
There is no lifecycle phase to do this but you can bind the exec-maven-plugin, specifically the exec:java goal to it. For example, to run the goal on the package phase:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>run-java</id>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>main.Class</mainClass>
</configuration>
</plugin>
What I am trying to achieve is integrate SonarQube analysis into the build process, so that whenever mvn clean install is run, the code is analyzed with SonarQube. We want to use it for local analysis and also for build on Jenkins. If new issues are found, than the build should fail (we want to use build breaker plugin for that). This way the developer would know that by his code his is going to introduce new issues, and will have to fix them for the build to work.
When I run mvn sonar:sonar, the analysis takes 30 seconds, which is OK.
However, the problem occurs when I am trying to bind sonar goal to maven build phases. I bind sonar to verify phase. The build takes 5 minutes now, which is too long. It should take about 1 minute. The build itself, without SonarQube analysis takes 30 seconds.
Note (may help to figure out what the problem is): the project on which the build is run has multiple modules in it, and I guess that is the problem. It looks like sonar:sonar goal is executed multiple times, once for each submodule, and the whole project is analyzed multiple times (not only the submodules). So, we have 4 submodules, and the report is generated 5 times during the build.
Instead, we want to analyze the whole project only once, not 5 times. It's also important for this 1 analysis to be run at the end of the build, after the cobertura reports are generated for all modules.
So, how do I integrate SonarQube analysis into the build, so that it analyzes my multi-module project only once, in the end, after cobertura reports are generated for all the submodules?
SonarQube plugin properties in parent pom:
<!-- Sonar plugin properties -->
<sonar.jdbc.url>jdbc:url</sonar.jdbc.url>
<sonar.analysis.mode>preview</sonar.analysis.mode>
<sonar.issuesReport.html.enable>true</sonar.issuesReport.html.enable>
<sonar.issuesReport.console.enable>true</sonar.issuesReport.console.enable>
<sonar.host.url>sonar.host:9000</sonar.host.url>
<sonar.language>java</sonar.language>
<sonar.buildbreaker.skip>false</sonar.buildbreaker.skip>
<sonar.qualitygate>Sonar%20way%20with%20Findbugs</sonar.qualitygate>
<sonar.preview.includePlugins>buildbreaker</sonar.preview.includePlugins>
<sonar.exclusions>file:**/target/**</sonar.exclusions>
<branch>development</branch>
Plugins configuration in the project pom:
<!-- Run cobertura analysis during package phase -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>cobertura</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
IMO, this is just a Maven configuration issue, you're missing the <inherited>false</inherited> element on the execution of sonar:sonar:
<!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
I kind of understand most things in Maven, but trying to understand goals is very frustrating. The main problem is that Maven seems to want to hide everything and anything to do with Goals.
If I have a plugin with an execution, and this execution has a goal,
does the goal attach itself somewhere near particular other goals?
How does it know which phase it belongs in?
Does it somehow replace some other goal?
Case in point :
<plugins>
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>wsimport-from-jdk</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<executable>${tool.wsimport}</executable>
<wsdlUrls>
<wsdlUrl>http://WorkPC:8080/server-web/AirlineWS?wsdl</wsdlUrl>
</wsdlUrls>
<packageName>com.bluewalrus</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
This is a wsImport goal which generates artifacts from a web service. It happens before I compile my project. How on earth can this XML tell me where this goal should execute? It just doesn't seem clear to me.
I mean what I am saying, is that I would expect something like "bind-to-process-resources right after goal-xyz". It all seems a bit nebulous to me.
Unfortunately, the pom.xml cannot tell you everything about how a plugin's goals are bound. A plugin can define a default lifecycle phase to bind to and this will not be reflected in the pom.xml. Looking at the documentation for the jaxws-maven-plugin I see this line for the wsimport goal:
Binds by default to the lifecycle phase: generate-sources.
You can override the lifecycle phase to bind to by adding a <phase> element to the plugin's <execution>. For example, if you wanted the goal to run right before packing the artifact (not sure why you would, but bear with me for this example) you could specify <phase>package</phase> after the execution <id>
I would recommend taking a look at the official Maven guide to configuring plugins for more details.
Also you would want to read:
The phases's order in standard lifecycles
The phases's bindings for lifecycle and packaging types
Let's say I have 5 different goals linked to Mojos that I want to be able to bind, named from goal-a to goal-e.
I would like to be able to bind them like maven lifecycle phases, i.e. if I define an execution path and I call a goal, all previous goals on this path are executed beforehand.
I would then have :
goal-a -> { goal-b -> goal-d
{ goal-c -> goal-e
So if I run mvn groupdId:artifactId:myPlugin:goal-d, it executes goal-a, goal-b, goal-d.
If i run the same command with goal-e, it executes goal-a, goal-c, goal-e.
Is there any way to define such bindings ?
You can write a custom plugin quite easily that will accomplish what you are looking for using the Mojo Executor.
For instance, you can write a Mojo for goal-d and in it, you can use the Mojo Executor to execute the goal-a and goal-b Mojos.
You can add execution of your plugin into <build> block or create separate profile for its run, and there define all goals. Here is an example:
<build>
<plugins>
<plugin>
<groupId>your.plugin.group.id</groupId>
<artifactId>your-plugin-artifact-id</artifactId>
<executions>
<execution>
<!-- here you need to specify build phase where your plugin execution will be started -->
<phase>install</phase>
<!-- here you can add all your goals to execute -->
<goals>
<goal>goal-a</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
When you execute phase install on project your plugin will execute its goals.