SonarQube and maven - maven

when I build my project I usually call mvn clean install.
Now I tried to integrate sonarqube analysis. Therefore I created a new Run Configuration in Eclipse where I execute the goal mvn sonar:sonar with some parameters.
Is there a way to run sonar:sonar within the mvn clean install automatially?

This should be documented in "Analyzing with SonarQube Scanner for Maven".
It will be triggered in the build phase.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.3.0.603</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Then see "Running sonar analysis with mvn sonar:sonar ignores sonar-project.properties".
To associate it with an existing lifecycle phase seems problematic.

Related

How to configure maven for executing test ONLY on deploy

I have maven surefire plugin on pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<includes>
<include>org.mycompany.service/*Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
Now I want maven to execute test ONLY on deploy goal, therefore:
When executing mvn deploy tests should run
When executing mvn package or mvn install, tests should not run because goals are prior to deploy
The only way I can think of to make this work would be to bind the surefire plugin to the deploy phase. This has drawbacks:
The tests are run after the artifacts was installed.
Maybe the tests break because they are not meant to be run that late in the lifecycle.
I am not sure how to make sure that they are executed before the deployment happens.
Do you want this behaviour by default, or do you want that just for you or in certain environments?
Adding -DskipTests to the command line is usually good enough.
I have some CLI aliases that I use on my local workstation, so I don't have to type all of it, and don't forget to add it. See e.g. for zsh: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/mvn

Specify Jacoco Version from Command Line when Running Maven Release

I have a need to specify jacoco dependency/plugin version from the command line when running the following command:
mvn release:prepare release:perform ...options... [JACOCO VERSION]
Basically, I want all projects to be built using the same jacoco version despite whatever version is present in their pom.
Is there a way to do this through the cli? I have seen examples doing this when specifying jacoco prepare agent, but I want to specify the actual jacoco-maven-plugin plugin version.
You can define the version inside the properties and set value from the command line.
For eg,
<properties>
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
</plugin>
</plugins>
</build>
While from the command line, specify the new property value.
mvn -Djacoco-maven-plugin.version=0.8.5
You can also verify the effective pom by running
mvn -Djacoco-maven-plugin.version=0.8.5 help:effective-pom

How to publish the artifacts at the end using maven-release plugin

I have a multi-module maven project. I'm using maven-release plugin to publish the artifact to maven repository. I'm using following command to do the above task.
mvn -B clean release:clean release:prepare release:perform -DautoVersionSubmodules=true '-DscmCommentPrefix=[maven-release-plugin]'
In one of the sub-module, i have a Unit test failure, but still i see the remaining modules are published to maven repo, except failed module.
Is there a way to publish all sub-modules only when the Unit tests for all modules pass?
Following is the maven pom configuration i have in Parent pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<tagNameFormat>v#{project.version}</tagNameFormat>
<localCheckout>true</localCheckout>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<localCheckout>true</localCheckout>
<pushChanges>true</pushChanges>
<mavenExecutorId>forked-path</mavenExecutorId>
<preparationGoals>clean deploy -U -B</preparationGoals>
<goals>clean install</goals>
<arguments>-Prelease</arguments>
</configuration>
</plugin>
The maven-deploy-plugin has a command line option "-DdeployAtEnd=true" that will accomplish this. But because maven-release-plugin runs the deploy command in its own instance of Maven, you have to pass it into this instance using the maven-release-plugin -Darguments option.
Overall, your command will look like this.
mvn -B clean release:clean release:prepare -Darguments=\"-DdeployAtEnd=true\" release:perform -DautoVersionSubmodules=true '-DscmCommentPrefix=[maven-release-plugin]

How to 'mvn jetty:run' from a parent pom?

I have a multi-module project that includes several .war packages. I would like to be able to 'mvn jetty:run' on the parent pom and have each of the sub-modules's .wars deployed on the same embedded jetty instance.
I am able to successfully run 'mvn jetty:run' from each of the the sub-modules, but when I run it on the parent pom it fails and skips the sub-modules.
Trying to run 'mvn jetty:run' from the parent pom results in the following:
[ERROR] Failed to execute goal
org.mortbay.jetty:maven-jetty-plugin:6.1.16:run default-cli) on
project FlashCards_App: Webapp source directory C:\dev\sour
ce_code\FlashCards_App\src\main\webapp does not exist -> [Help 1]
It's true there is no webapp directory on the parent pom.
Here's an excerpt from my pom. The full file can be found here.
<modules>
<module>FlashCards_Domain</module>
<module>FlashCards_GWT</module>
<module>FlashCards_Service</module>
<module>FlashCards_Service_SpringData</module>
<module>FlashCards_Service_Jpa</module>
<module>FlashCards_WebServices</module>
<module>FlashCards_Struts</module>
<module>FlashCards_Test</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
</plugins>
</build>
This is basically the same question asked in 2009 in this post. It's been a few years and I'm wondering if there are any other options available now. The previous post proposes two solutions (1) using cargo plugin and (2) building sister wars from a sub-module.
Your best shot is probably to configure the jetty plugin to run multiple webapps. I'm not sure if it would work from your parent pom though, so you might have to use on of your modules as the "launcher" webapp, or create a "dummy webapp" in your parent project.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.6.v20141205</version>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
<war>${project.basedir}/app1/target/app1.war</war>
<contextPath>/app1</contextPath>
</contextHandler>
<contextHandler implementation="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
<war>${project.basedir}/app2/target/app2.war</war>
<contextPath>/app2</contextPath>
</contextHandler>
</contextHandlers>
<stopPort>9999</stopPort>
<stopKey>STOP</stopKey>
</configuration>
</plugin>
cd parent_module
mvn jetty:run -pl sub_module
cd parent_module
mvn jetty:run -pl sub_module
To complete #jiahut answer:
$ mvn jetty:run --help
(...)
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
(...)
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path
Example from Apache Archiva:
mvn jetty:run -pl :archiva-webapp -am

tomcat-maven-plugin with multi module and war overlay

I have a maven war project (call it projectA) that depends on another maven war (call it projectB). They get integrated using an overlay with the maven-war-plugin. Both projects have the same parent and the same aggregator (different from the parent). I can package the final war successfully without any issue. This is the command I'm running to do that (I'm at the aggregator level when running mvn):
mvn -am -pl projectA package
The reactor build order is parent ➡ projectB ➡ projectA and all is fine.
I'm now trying to use the tomcat-maven-plugin in this build. So I added the tomcat-maven-plugin in the parent pom pluginManagement section and used it in the projectA pom. I'm launching tomcat with:
mvn -am -pl projectA tomcat:run
The reactor build order remains the same. But the tomcat execution is run on projectB (which is also a war) and not on projectA. Actually, projectA build is not even reached.
I've tried with both the org.codehaus.mojo.tomcat-maven-plugin v1.1 and org.apache.tomcat.maven.tomcat6-maven-plugin v2.1, I've found the same behavior.
How can I make tomcat run the final projectA?
Note: The project dependencies are in fact a bit more complicated and there are other sub-projects involved (jars), that's why I'm calling maven with -am (also make).
Ok, so I found a solution. It is to disable the maven-tomcat-plugin for the pojectB, this answer is based on this other question.
Linking the plugin to a specific phase
First I had to link the maven-tomcat-plugin to a phase of my build cycle, so that it is called even if I don't call the plugin directly from the CLI, obviously I choose the integration-test phase. I can now run mvn integration-test -pl projectA to have tomcat being launched with the just build war.
This is how the plugin is declared in the parent:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>run-war</id>
<!-- We link this plugin to some non default phase so that we can disable it in some modules. -->
<phase>integration-test</phase>
<goals>
<goal>run-war</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
and in projectA I just make use of it as declared in the parent:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
</plugin>
</plugin>
</build>
Deactivating the plugin in projectB
Then, in projectB, I link the same plugin (with the same id) to a null/void/empty phase, which ends up disabling the plugin for this project when built for this integration-test phase:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
<executions>
<execution>
<id>run-war</id>
<!-- We don't want this plugin to be called from another module build -->
<phase/>
</execution>
</executions>
</plugin>
</plugins>
</build>
With that setup, I can now do a complete build (both projectB, projectA and other dependencies) and launch tomcat with the resulting war in a single run:
mvn -am -pl projectA clean integration-test

Resources