I defined a profile at my base-pom which uses a property that is defined by a sub-pom (deploy-location of the appserver-module). The profile shall be used after the initial full-build and thus be inherited to all sub-poms.
The question is: how/when are such properties resolved: when doing the initial full build or when doing a local build of a specific submodule ?
<profile>
<id>quickdeploy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${ear.path}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
${ear.path} is defined in a submodule ...
I just tried out your question a created two artifacts with m2eclipse. The first is q4794952.base which is a simple maven project and has its type set to pom. Then I created the second artifact from (right click on the base project, New => Maven => Maven Module ) which automatically creates the parent tag and the (sub)module inside the base artifact.
When using a module structure like created by the process above (or in genereal where the module is known by the tag) the property from the submodule is know to the "base" and will be resolved in the "full-Build" (as can be seen by using help:effective-pom and the build result of course). If you build just the submodule it's resolved as well because the profile is taken from the parent pom and the property is set in the (sub)module.
Here's my "basepom":
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>q4794952.base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>quickdeploy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${ear.path}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<modules>
<module>q4794952.sub</module>
</modules>
</project>
Related
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>
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.
I have a project that is using several profiles. Each profile uses following plugins:
maven-compiler-plugin
maven-resources-plugin
maven-antrun-plugin
maven-surefire-plugin
maven-war-plugin
The one marked in bold is however the only plugin where there is a difference between the profiles (different configuration files will be copied using the antrun plugin). The 4 other plugins are configured exactly the same for all profiles.
The question is now: is there some way to include these common plugins only once but still use them for all the profiles by default?
Something like:
<shared><plugin1><plugin2>...</shared>
<profile><plugin3></profile>
<profile><plugin3></profile>
...
thanks,
Stijn
If a plugin is used by all profile, simply define it in the <build> part :
<project>
...
<build>
<plugins>
Your shared plugins go here...
</plugins>
<profiles>
Definition of profiles...
</profiles>
</project>
This way, you will only define the antrun plugin in the profiles block.
Just include the common plugins in your build section:
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>plugin1</artifactId>
</plugin>
...
</plugins>
</build>
Then add the specific plugin in your profile:
<profiles>
<profile>
<id>...</id>
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>plugin3</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You can also configure the same plugin differently in different profiles this way:
<profiles>
<profile>
<id>profile1</id>
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>plugin1</artifactId>
<configuration>
<setting>value1</setting>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>profile2</id>
<build>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>plugin1</artifactId>
<configuration>
<setting>value2</setting>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
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.
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.