Configure Maven plugins to stick together - maven-2

I have parent pom which configures certain plugins
<pluginManagement>
</plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
...
</plugin>
</plugins>
</pluginManagement>
And I have tree of poms which are represent integration tests
A-\
a1
a2
B-\
b1
b2
C-\
D-\
d1
d2
In each a,b,d products I do
<build>
<plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</build>
The problem is when I will need to add fourth plugin to integration test process for example my custom plugin I will need to move
through all of the integration modules and do manual adding.
You can advice me to remove <pluginManagement> to allow all child just to use them implicitly.
Yes, but in products which are just 'pom' I don't want plugins to do anything: create some resources and put jboss configuration directories.
I wonder is there some kind of
<pluginsBundle>
<groupId>my.group</groupId>
<artifactId>my-integration-test-bundle</artifactId>
<plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</pluginsBundle>
To allow me use it just like
<plugin>
<groupId>my.group</groupId>
<artifactId>my-integration-test-bundle</artifactId>
<runOnce>true</runOnce>
</plugin>
I would like to add option like
<runOnce>true</runOnce>
to be able to start application server and deploy target only one time per maven launch.

I don't know of a mechanism that does exactly what you need. Your best bet is to define a parent pom with those plugins defined in the build section, rather than the pluginManagement section. In this case the plugin configuration will always be defined. Adding the configuration to a profile in the parent means you can exercise some control over the activation of those plugins.
One refinement to consider is that you can control activation of a profile by the presence or absence of a file. This way you can define the profile in the parent, but have it deactivated in that project because of the marker file being present in the parent. Child projects would not have the marker file in their source, so the profile would be activated for those projects. You can reverse the behaviour by using missing instead of exists if that makes sense for the majority of projects.
<profile>
<id>build</id>
<activation>
<file>
<missing>src/main/resources/build.marker</missing>
<!-- or if you want to enable the profile when the file does exist:
<exists>src/main/resources/build.marker</exists-->
</file>
</activation>
<build>
</plugins>
<plugin>
<artifactId>gmaven-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
...
</plugin>
<plugin>
<artifactId>cargo-maven2-plugin</artifactId>
...
</plugin>
</plugins>
</build>
</profile>
Alternatively, you could try writing custom plugin with a lifecycle that executes all the required mojos in a forked lifecycle. I recently answered another question with details of how to do this.
Another alternative is to write another plugin that uses Maven shared-io to apply a descriptor
to the pom, that descriptor can define arbitrary configuration that is merged into the pom. Another answer describes how this can be done.

AFAIK, there is no way to declare a bundle of plugins that could be used somewhere else... but there is inheritance.
What about creating a pom with the <plugins> declaration in the <build> section and inheriting from this pom in your integration tests projects? This looks like feasible.

Related

"No public or protected classes found to document" error from path with accents

My Maven Java 8 project is inside a path which contains accents: C:\Développements\myproject.
When I use maven-javadoc-plugin (event with last 2.10.4 version) I have this error when I try to generate the javadoc of my project (from IntelliJ IDEA 2016.2.4):
[ERROR] javadoc: warning - No source files for package com.mycompany.myproject
[ERROR] javadoc: error - No public or protected classes found to document.
This is strange because I have documented classes in this project.
This error can also occur if you have no public methods in your test classes, which is exactly what can happen because Sonar lint rule S5786 says JUnits should have default package visibility, for readability. Fortunately, you can use the -package javadoc option, to fix this. If you put this in your parent pom:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.version>3.8.1</maven.compiler.version>
<junit.version>5.7.0</junit.version>
</properties>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.9.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<source>8</source>
<additionalOptions>-package</additionalOptions>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<distributionManagement>
<site>
<id>yourid</id>
<url>file:///var/www/html/maven</url>
</site>
</distributionManagement>
then
mvn site-deploy
will give you your default maven site along with the javadoc. Included everything relevant for a Java 8 project.
Had this happen when I created a package-private class with a main method. After marking the class as public the packaging step worked again.
This is not a Maven or plugin problem but purely a Windows problem. Microsoft is too stupid to have a proper encoding set in cmd.exe. You have some stupid DOS encoding. Java's javadoc uses that to read the #options file and fails.
Set _JAVA_OPTIONS=-Dfile.encoding=UTF-8 and you are done. Alternatively, use a Linux distribution or FreeBSD.
The issue remains closed.
Actually this is a referenced bug from maven-javadoc-plugin project: MJAVADOC-333.
So since it is not fixed (it is currently "closed"...) one should just remove the accents from your project path...
Apart from the special character (accent) problem, this may be a problem with your pom.xml:
I had the same problems right now with a project created in Eclipse.
If you create a project in eclipse, it will put java packages/sources directly within the src folder and add the following line to your pom.xml:
<sourceDirectory>src</sourceDirectory>.
If you then decide to move your java files according to the maven conventions and forget to update or remove the sourceDirectory tag, you will end up with exactly the same error:
Your project will build fine, but javadoc will not find it`s sources...

Maven: specify the outputDirectory only for packaging a jar?

How can I specify the outputDirectory only for packaging a jar?
http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html this shows all parameters, but how can I set them in the commandline or pom.xml?
on command line
-DoutputDirectory=<path>
and in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>/my/path</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
Parameter Expressions
About command line usage:
The parameter documentation specifies that the parameter is initialized to the value of the property ${project.build.directory} (which is the property referring to the target folder)
Here's what this means:
For mojos that are intended to be
executed directly from the CLI, their
parameters usually provide a means to
be configured via system properties
instead of a <configuration/> section
in the POM. The plugin documentation
for those parameters will list an
expression that denotes the system
properties for the configuration. In
the mojo above, the parameter url is
associated with the expression
${query.url}, meaning its value can be
specified by the system property
query.url as shown below:
mvn myquery:query -Dquery.url=http://maven.apache.org
Reference:
Guide to Configuring Plug-ins > Generic Configuration
Configuring ${project.build.directory}
However, ${project.build.directory} is not a system property, it's a property of the Project's Build object.
You can't set maven's internal properties directly on the command line, but you can get there with a little trick by adding placeholders in your pom.xml:
<build>
<directory>${dir}</directory>
</build>
Now, the output directory is set via the property from the command line (using -Ddir=somedirectory). Downside: now you always have to use the -Ddir parameter on the command line.
Using Profiles
But there's help here, too. Just use a profile when you want to configure the directory:
<profiles>
<profile>
<id>conf</id>
<build>
<directory>${dir}</directory>
</build>
</profile>
</profiles>
Now you can either do
# everything goes in someOtherDir instead of target
mvn clean install -Pconf -Ddir=someOtherDir
or plain old
# everything goes in target
mvn clean install
Configuring the Jar Plugin
Now if you just want to change the jar outputDirectory from the command line without redirecting everything from target, we'll modify the profile to configure the plugin from a command line property:
<profiles>
<profile>
<id>conf</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>${dir}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The usage is identical to above:
# everything goes in someOtherDir instead of target
mvn clean install -Pconf -Ddir=someOtherDir
Thanks #Sean Patrick Floyd for the excellent explanation.
Instead of creating a profile and using mvn always by -P switch, I'd like to use another way that making a default value of property ${dir}.
Just define ${dir}'s default value as ${project.build.directory}
<properties>
<dir>${project.build.directory}</dir>
</properties>
and same as #Sean Patrick Floyd, set outputDirectory.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>${dir}</outputDirectory>
</configuration>
</plugin>
</plugins>
Now you can either do
# everything goes in someOtherDir instead of target
mvn clean install -Ddir=someOtherDir
or plain old
# everything goes in target
mvn clean install
If you wish copy dependency jars as well to a target folder, use maven-dependency-plugin.
<project>
...
...
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

maven2: how to share a plugin configuration between parent and children pom?

I'm trying to reduce copy/pasting in our maven pom files.
We have one master pom and many children projects pom inheriting from the master.
I want to share a complex plugin definition looking like:
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<configuration>
<!-- many xml lines here -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
<goal>generate-daemons</goal>
<goal>create-repository</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo.appassembler</groupId>
<artifactId>appassembler-booter</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
When this plugin definition is in the project pom, packaging is well done.
When definition is moved to parent pom (in or in ), then the packaging is not even started.
Is it possible to share a plugin configuration ? How ?
-- Edit after first answers---
I have tried the following:
- put my XL packaging plugin config in the element of my parent pom
- add this lines in my project pom in the element:
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
</plugin>
...
</plugins>
but it is not working...
What can be wrong with that ?
-- last edit --
I think I get what was the problem:
the plugin re-use declaration should be declared in a profile build.
I done that in an always enabled plugin and now it is working fine.
Thanks a lot.
You could wrap the plugins of the parent in a <pluginManagement> tag.
<build>
<pluginManagement>
<plugins>
<plugin> ... </plugin>
</plugins>
</pluginManagement>
</build>
Children plugins will then inherit the configurations when they declare the plugin in their build tag.
Have you tried using the plugin management feature of Maven? It'll allow you to push that configuration information down to the children pom.xml files from the parent pom.xml:
<build>
<pluginManagement>
<plugins>
<plugin>your_plugin</plugin>
</plugins>
</pluginManagement>
</build>
Now, not all plugins are as well done as those from the org.apache.maven.plugins group. It may be necessary to move your configuration section in between your execution elements.

Maven2 - problem with pluginManagement and parent-child relationship

from maven documentation
pluginManagement: is an element that is seen along side plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement definitions.
Now : if I have this in my parent POM
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
and I run mvn help:effective-pom on the parent project I get what I want, namely the plugins part directly under build (the one doing the work) remains empty.
Now if I do the following :
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<inherited>true</inherited>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
mvn help:effective-pom I get again just what I want, the plugins contains just what is declared and the pluginManagement section is ignored.
BUT changing with the following
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<executions>
some stuff for adults only
</execution>
</executions>
</plugin>
</plugins>
</build>
and running mvn help:effective-pom
the stuff from pluginManagement section is added on top of what is declared already. as such :
<build>
<pluginManagement>
...
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<executions>
Some stuff for the children
</execution>
<executions>
some stuff for adults only
</execution>
</executions>
</plugin>
</plugins>
</build>
Is there a way to exclude the part for children from the parent pom's section ? In effect what I want is for the pluginManagement to behave exactly as the documentation states, that is I want it to apply for children only but not for the project in which it is declared.
As a corrolary, is there a way I can override the parts from the pluginManagement by declaring the plugin in the normal build section of a project ? whatever I try I get that the section is added to executions but I cannot override one that exists already.
EDIT:
I never did find an acceptable solution for this and as such the issue remains open. Closest solution was offered below and is currently the accepted solution for this question until something better comes up. Right now there are three ways to achieve the desired result (modulate plugin behaviour depending on where in the inheritance hierarchy the current POM is):
1 - using profiles, it will work but you must beware that profiles are not inherited, which is somewhat counter intuitive. They are (if activated) applied to the POM where declared and then this generated POM is propagated down. As such the only way to activate the profile for child POM is specifically on the command line (least I did not find another way). Property, file and other means of activation fail to activate the POM because the trigger is not in the POM where the profile is declared.
2 - (this is what I ended up doing) Declare the plugin as not inherited in the parent and re-declare (copy-paste) the tidbit in every child where it is wanted. Not ideal but it is simple and it works.
3 - Split the aggregation nature and parent nature of the parent POM. Then since the part that only applies to the parent is in a different project it is now possible to use pluginManagement as firstly intended. However this means that a new artificial project must be created that does not contribute to the end product but only serves the could system. This is clear case of conceptual bleed. Also this only applies to my specific and is hard to generalize, so I abandoned efforts to try and make this work in favor of the not-pretty but more contained cut and paste patch described in 2.
If anyone coming across this question has a better solution either because of my lack of knowledge of Maven or because the tool evolved to allow this please post the solution here for future reference.
Thank you all for your help :-)
Adding the plugin configuration to pluginManagement means that this configuration will be used if the plugin is declared, but you still need to declare the plugin in the build section of any POM that wants to use it.
The key part that explains this from the section you quoted is:
However, this only configures plugins that are actually referenced within the plugins element in the children
So if you do this in the child pom the configuration from the parent will be applied:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
</build>
Update: To answer the actual question, the content from the pluginManagement section is always merged with any plugin declaration. To avoid the parent doing this, you can define the pluginManagement section within a profile, and activate that profile on child projects but not the parent. The child projects would then have to declare that profile.
For example:
<profiles>
<profile>
<id>for-children</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
<!--Some stuff for the children-->
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<!--some stuff for adults only-->
</executions>
</plugin>
</plugins>
</build>
I always used to think that a child POM can inherit a plugin definition from its parent's pluginManagement section and specify only the executions it wants to run from that plugin by referencing them by ID and binding the execution to a phase. As long as the parent definition is in pluginManagement (and not directly in plugins) and is not bound to a phase, only the specific execution (with ID) will be run in that phase.
From reading the above, and from my own current problem, it looks like that's not true: it looks like a child POM will inherit the entire configuration of the plugin, including all executions. In terms of executions, the only thing the child can do is to override specific values - it cannot pick which executions to run, and which not to.
Is this a bug? What's the use of being able to bind each execution to a phase (or not), if all executions will be run? I've only seen it with maven-dependency-plugin:unpack (bound to package phase), but with other plugins I might just have been lucky...
Damn.
In parent pom you should configure executions with <goals> declared but don't declare <phase>. Then in the child POM you should declare:
<plugin>
<artifactId>some-plugin</artifactId>
<executions>
<execution>
<id>execution-id</id>
<phase>partcular-phase</phase>
</execution>
</executions>
</plugin>
The plugin won't be executed until you define a phase in the child pom. Therefore you'll need to explicitly bind executions to phases in every child POM (or in the middle of hierarchy), but
you won't need to copy-paste configuration of these executions.
Note, that many of plugins have Default Phase, e.g. Enforcer Plugin is bound to validate by default. Even if you don't bind plugin to a phase explicitly, it will be bound anyway and thus the plugin will be executed. To overcome this, use non-existing phase in your parent:
<execution>
<id>execution-id</id>
<goals><goal>some-goal</goal></goals>
<phase>none</phase>
</execution>
You must assign an ID to the execution so maven knows which ones overwrite each other and which are independent.

Is it possible to override the configuration of a plugin already defined for a profile in a parent POM?

In a POM parent file of my project, I have such a profile defining some configurations useful for this project (so that I can't get rid of this parent POM) :
<profile>
<id>wls7</id>
...
<build>
<plugins>
<!-- use java 1.4 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<fork>true</fork>
<source>1.4</source>
<target>1.4</target>
<meminitial>128m</meminitial>
<maxmem>1024m</maxmem>
<executable>%${jdk14.executable}</executable>
</configuration>
</plugin>
</plugins>
</build>
...
</profile>
But in my project I just would like to override the configuration of the maven-compiler-plugin in order to use jdk5 instead of jdk4 for compiling test-classes.
That's why I did this section in the POM of my project :
<profiles>
<profile>
<id>wls7</id>
<activation>
<property>
<name>jdk</name>
<value>4</value>
</property>
</activation>
<build>
<directory>target-1.4</directory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>my-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<fork>true</fork>
<executable>${jdk15.executable}</executable>
<compilerVersion>1.5</compilerVersion>
<source>1.5</source>
<target>1.5</target>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...
</profiles>
and it's not working ...
I even tried to override the configuration in regular plugin sections of my POM (I mean, not for a specific profile but for my whole POM).
What could be the problem ?
To clarify some of my requirements :
I don't want to get rid of the parent
POM and the profile (wls7) defined
inside it (since I need many and many
properties, configurations, ...) and
that is not the process in my
company.
A solution based on duplicating
the parent POM and/or the profile
defined inside it is not a good
one. Since if the responsible of
the parent POM change something, I
would have to report it in mine.
It's just an inheritance matter (extend or override a profile, a configuration from an upper-level POM) so I think it should be possible with Maven 2.
Overriding configurations from a parent pom can be done by adding the combine.self="override" attribute to the element in your pom.
Try changing your plugin configuration to:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>my-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration combine.self="override">
<fork>true</fork>
<executable>${jdk15.executable}</executable>
<compilerVersion>1.5</compilerVersion>
<source>1.5</source>
<target>1.5</target>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
For more information on overriding plugins, see: http://maven.apache.org/pom.html
i had the same issue. By default my maven war plugin excluded a html file. But in my acceptance-tests profile i wanted this file included. So when i added in the maven war plugin again it did not override the default.
To resolve this issue i passed in the combine.self attribute and worked fine.
Default build:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<packagingExcludes>swagger-ui/client.html</packagingExcludes>
</configuration>
</plugin>
Acceptance test profile:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration combine.self="override"/>
</plugin>
Did you try to deactivate the wls7 profile (since maven 2.0.10):
Starting with Maven 2.0.10, one or
more profiles can be deactivated using
the command line by prefixing their
identifier with either the character
'!' or '-' as shown below:
mvn groupId:artifactId:goal -P !profile-1,!profile-2
This can be used to deactivate
profiles marked as activeByDefault or
profiles that would otherwise be
activated through their activation
config.
And then add your configuration in a profile with a different name or directly in your pom.xml.