Arranging Profiles and Plugins in pom.xml - java

I have these things in my pom.xml
profile1
profile2
These profiles are for separate build environment.
I need to make these plugins as common to both profiles.
plugin1
plugin2
plugin3
Where should I place these common plugins?

You can simply put them in the default build section. Since the plugins are common to both profiles: this the best way to do it.
Remark that if the configuration of plugins is slightly different for the different profiles you can use properties in the plugin configuration and define the values of those properties in the profile.
<build>
<plugins>
<plugin>
<groupId>someGroup</groupId>
<artifactId>plugin1</artifactId>
...
</plugin>
<plugin>
<groupId>someGroup</groupId>
<artifactId>plugin2</artifactId>
...
</plugin>
<plugin>
<groupId>someGroup</groupId>
<artifactId>plugin3</artifactId>
...
</plugin>
</plugins>
</build>
EDIT
Note that this solution will enable the plugins even when no profiles are activated. Not sure this what you need. (you maybe have a third build environment: for instance the developper computer where no profile are defined). In this case the solution of a third profile is the way to go.
mvn clean install -Pprofile1,profile-common
or
mvn clean install -Pprofile2, profile-common
and your common plugins defined in profile-common

You can have multiple profiles active at any given point of time. As such you can create a common profile( profile3) and keep the plugins there. The plugins/config which are dependent on specific profiles, can be kept in specific profile1 and profile2.
-P profile-1,profile-3

Related

Global changes to maven surefire plugin in .m2/settings.xml

I would like to change the default setting for maven-surefire-plugin, and instead of using <reportFormat>brief</reportFormat>, I would like to use <reportFormat>plain</reportFormat>.
Usually, I would achieve this by modifying an individual pom for a project, such as:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<reportFormat>plain</reportFormat>
</configuration>
</plugin>
However, is it possible to somehow modify ~/.m2/settings.xml file and set <reportFormat>plain</reportFormat> as a default behaviour for all maven projects I want to compile.
I do an analysis of many maven projects, so I would prefer to change the behaviour on global level rather than modifying pom files for each individual project.
The settings.xml configuration file doesn't go down at this level of detail. The plugin configuration can be specified only in the pom.xml
The best way to check it is studying the settings.xml schema :
https://maven.apache.org/xsd/settings-1.0.0.xsd
You could see that the single elements referencing the "plugin" word have no relation with the plugin configuration in the build.
For your requirement, the single solution that has also its drawbacks if bad used is using a parent pom that defines the plugin configuration and that all Maven modules should have as parent to inherit from the plugin configuration and potentially from other things.
If your applicative projets use a multi module/parent pom structure, I think that a nicer solution would be to declare this configuration in the parent pom of each multi module/parent pom.
In this way you declare it multiple times but a single time by set of related projects.

Automatically install a project in the local repository?

I'm trying to work around a maven bug MDEP-187 ( https://issues.apache.org/jira/browse/MDEP-187 ) by not using workspace resolution.
This forces me to do a mvn install for all my dependencies, I'm doing this by creating a launch configuration in eclipse with goal install.
The problem is that i have to create a launch config for every project in my multiproject workspace, in addition to install i have to manually call every launch config and run it. Which just doesn't work.
Is it possible to automatically install a project in the local repository? (whenever i update my code)
If you don't need to run dependency:copy in Eclipse, you can use following work-around:
Add a profile to your pom.xml, something like this:
<profiles>
<profile>
<id>copy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
[...]
</executions>
</plugin>
</plugins>
<build>
<profile>
</profiles>
Enable workspace resolution in Eclipse.
Then Eclipse will not use dependency:copy, but you can use dependency:copy with command line: mvn install -P copy.
I did go with #khmarbaise solution:
But than you need to can handle the whole thing via
maven-assembly-plugin which can create archives / folders with all the
dependencies. Apart from that a swing ui must be started somehow which
will need some kind of shell script / batch file which you can create
by using appassembler-maven-plugin...And it sounds like you need to go
for a multi module project in maven..cause you might have parts like
core, ui, etc. which are needed to be combined in the end.
#khmarbaise i was in the understanding that the assembly-plugin didn't
support putting dependencies in a lib/ folder (just putting everything
in 1 big jar), but after a little bit of trying i just go myself a zip
with a runnable jar and my dependencies in a lib/ folder. Tomorrow i'm
going to read a bit more about the assembly-plugin. I'm happy ;-

Maven plugin configuration vs properties

What are pros and cons of configuring Maven plugins through properties as oppose to configuration?
For example, maven-compiler-plugin documentation explicitly shows configuring source and target as
shown below, presumably going even further with pluginManagement.
https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.4</source>
<target>1.4</target>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
Wouldn't it be more succinct to use user properties instead, with no dependency on specific version?
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
First of all, many parameters of many goals do not have any associated user property, so can only be set via <configuration>.
For those which do have a user property (such as these examples), it depends. A few user properties are specifically coördinated between multiple goals or even plugins, as #khmarbaise points out.
User properties can be overridden from the command line, as #kdoteu points out, which is useful in certain cases—though very likely not for Java source/target level which would normally be intrinsic to the project (something you would change in a versioned commit alongside source file changes). User properties can also be overridden from external profiles such as in settings.xml, which is occasionally important.
On the other hand, plugin configuration is more explicit: it is expressly associated with a particular goal (or all goals in a plugin using the same parameter name). Some IDEs can offer code completion. You need not worry about accidentally having some other unrelated plugin interpret a property name (though plugin authors try to use unique-looking prefixes for most user property names). Surprisingly, Maven (3.8.1) will not fail the build if you mistype the parameter name, however—it will just quietly ignore the extra element.
You can influence the properties druing build time with commandline parameters. And you can use them in multimodule projects.
So wie are using them to configure findbugs or some urls for deploying.
There are some properties which are automatically taken by plugins. One for example are the given target/source information. An other is the project.build.sourceEncoding which is taken into account of several plugins like maven-compiler-plugin, maven-resources-plugin etc. So it makes sense to use properties which reduces the size and number of your configurations for plugins.

How does Maven understand release:prepare command?

I'm trying to create a plugin which would download and install jars from Maven central as system tools. So I want my line to be like
mvn install-plugin:install org.chaschev:cap4j:1.0
similar to Ruby's
gem install capistrano
This plugin would gather all the needed information about the shortcuts to create from the JAR. I.e. this jar would contain a class implementing an installation interface.
How does Maven understand that in order to execute a command like release:prepare it requires to download the release plugin and to run it? Any better/other way to do this?
Do you mean how the relation between plugin/goal in the comamnd line and plugin implementation is defined? Then the answer is plugin.xml. See plugin.xml for release plugin, e.g. maven-release-plugin-2.0.jar:
<goalPrefix>release</goalPrefix>
...
<mojos>
<mojo>
<goal>help</goal>
...
<mojo>
<goal>prepare</goal>
...
Or do you mean, how Maven discovers which plugins are available? Then the answer is:
There are two default groups where plugins are searched, org.apache.maven.plugins and org.codehaus.mojo
For your own plugin you may want to use name ${prefix}-maven-plugin, e.g. cap4j-maven-plugin
You can keep your name cap4j, but then put the plugin description to your POM, under <plugins>
If you want your build to work at other machines, they should point <pluginRepositories> in POM or in settings.xml to your plugin repository
It is not good to use default Maven groups for your own project.
Instead, define your own group for your plugin, like this:
<pluginGroups>
<pluginGroup>org.chaschev</pluginGroup>
</pluginGroups>
And rename your plugin from cap4j to cap4j-maven-plugin. Then Maven will discover your plugin without further cahnges in POM.
Alternative, without <pluginGroups>, just put following to your POM:
<plugins>
<plugin>
<groupId>org.chaschev</groupId>
<artifactId>cap4j</artifactId>
<version>...</version>
<configuration>
...
</configuration>
</plugin>
...
</plugins>

maven surefire reporting plugin configuration

I have a multi-module maven project. The parent pom.xml is simply a way to reference common information for the 4 subprojects. I have quite a few JUnit tests that run and I also have the Parent Project set up for Project WebSite using the maven-info-reports-plugin.
I have the maven-surefire-report-plugin configured in the parent and it generates the target/site/surefire-report.html file in each of the subprojects with the correct information.
My problem is when I run my project website via site:run I do not see any of the surefire-report.html files in the Project website. The one that shows is in the target directory of the parent and it has no unit tests defined.
Is there a way I can configure maven-surefire-report-plugin or maven-info-reports-plugin to aggregate the subprojects generated surefire reports?
To elaborate on Seph's answer. You can set many of the Maven reports to aggregate results. To do this with the surefire-report plugin you'd do something like this:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<aggregate>true</aggregate>
<!--also set this to link to generated source reports-->
<linkXRef>true</linkXRef>
</configuration>
</plugin>
</plugins>
</reporting>
Note the additional linkXRef property, this allows you to add cross-references to the generated html version of the source produced by the jxr plugin. The jxr plugin can also be set to aggregate, so the two combined allow you to browse your entire project structure.
As far as I know, the maven-info-reports-plugin doesn't do aggregation.
You can add
<aggregate>true</aggregate>
to the surefire plugin in the parent pom.xml.
For command line
mvn surefire-report:report -Daggregate=true
It could be -
mvn clean test -fn surefire-report:report -Daggregate=true
OR
mvn clean install -fn surefire-report:report -Daggregate=true
Note :
fn -> NEVER fail the build, regardless of project result
To add in pom
<aggregate>true</aggregate>

Categories