Right now, I'm writing a small java application by my own, with few maven pom.xml files. I want to make all my maven packages to compile with jdk 1.6, and I can't find a good way to do it without manually setting it on every single POMs - I'm sick of copy-and-pasting
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
in every single pom.xml file I generate.
Is there a simpler way to resolve this issue?
Create a pom-only (<packaging>pom</packaging>) project that has the compiler settings (and any other default settings) you want. You give treat it like any other project (release it; deploy it to your Maven repo, etc.).
Put a parent declaration at the top of your pom files:
<parent>
<groupId><!-- parent's group id --></groupId>
<artifactId><!-- parent's artifact id --></artifactId>
<version><!-- parent's version --></version>
</parent>
It doesn't help much if all you want to set is compiler settings. But if you find yourself configuring lots of plugins, reports and dependencies in the same way across project, you can create one parent to rule them all.
BTW - be careful about declaring dependencies and plugins in your parent pom file. Usually you'll want to favor dependencyManagement and pluginManagement. See the documentation for more details.
You could specify this plugin and configuration in your ~/.m2/settings.xml, which will then apply it to all projects.
However this has the downside of making your projects no longer portable - attempting to build the same code with the same pom.xml will fail on other machines that don't have the same settings.xml values as you.
I'm sick of copy-and-pasting
Yes, and you should use POM inheritance to avoid this and configure the maven-compiler-plugin in the parent POM.
Another option would be to use the solution suggested by #matt (and he nailed down pros and cons of the use of settings.xml).
In both cases, this is typically a setting that I like to check using the maven-enforcer-plugin and its requireJavaVersion rule that you would configure like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
But it can do more (like checking the maven version). Very useful.
I want to make all my maven packages to compile with jdk 1.6
If this is multi-module project just put these settings to top-level POM under pluginManagement.
If you have many independent project just copy-and-paste this configuration. Beware of "smart" solutions like setting this somewhere globally. Some day you will want to use different compiler settings for one or two of your projects and the nightmare will begin :-)
Remember...
Keep things as simple as possible, but no simpler.
Related
I have a Java monorepo with a few child projects, each corresponding to a different service. I am trying to convert one of these from Dropwizard to Micronaut, while leaving the others using Dropwizard.
pom.xml
|--service1 <--- converting this, and only this, to Micronaut
| `--pom.xml
|--service2
| `--pom.xml
The top-level pom.xml contains common dependencies, plugins, etc. the child projectgs inherit via the <parent> mechanism. All of the Micronaut documentation, examples and project builder set the micronaut-parent artifact as the project's parent. I'm unable to figure out how to keep the existing inheritance while also getting all of the features from the micronaut-parent artifact.
Is there a way to have a Micronaut project without the inheritance, but with the features micronaut-parent provides? Is there some other workaround?
Brute-force way of doing this is manually including the dependencies and plugins that are provided by the micronaut-parent artifact in your project's pom.xml file.
Also you should not forget to include the following to have plugins that are provided by micronaut-parent:
<build>
<plugins>
<plugin>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-maven-plugin</artifactId>
<version>${micronaut.version}</version>
<executions>
<execution>
<goals>
<goal>create-config</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
One last touch is to have a property micronaut.version in your pom that you want to use.
This is a snippet of my pom file.
....
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
......
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
I use it successfully with the command
mvn install
But, when I try to enclose it into the "pluginManagement" tag, the maven-dependency-plugin stops working when I launch the install goal.
Why does the "pluginManagement" tag change the build behavior? Or should I use another goal or option?
You still need to add
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
in your build, because pluginManagement is only a way to share the same plugin configuration across all your project modules.
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.
The difference between <pluginManagement/> and <plugins/> is that a <plugin/> under:
<pluginManagement/> defines the settings for plugins that will be inherited by modules in your build. This is great for cases where you have a parent pom file and would like to avoid having to copy the same code for the configuration of the plugin over to each of these modules.
<plugins/> is a section for the actual invocation of the plugins. It may or may not be inherited from a <pluginManagement/>.
You don't need to have a <pluginManagement/> in your project, if it's not a parent POM. However, if it's a parent pom, then in the child's pom, you need to have a declaration like:
<plugins>
<plugin>
<groupId>com.foo</groupId>
<artifactId>bar-plugin</artifactId>
</plugin>
</plugins>
Notice how you aren't defining any configuration. You can inherit it from the parent, unless you need to further adjust your invocation as per the child project's needs.
For more specific information, you can check:
The Maven pom.xml reference: Plugins
The Maven pom.xml reference: Plugin Management
You use pluginManagement in a parent pom to configure it in case any child pom wants to use it, but not every child plugin wants to use it. An example can be that your super pom defines some options for the maven Javadoc plugin.
Not each child pom might want to use Javadoc, so you define those defaults in a pluginManagement section. The child pom that wants to use the Javadoc plugin, just defines a plugin section and will inherit the configuration from the pluginManagement definition in the parent pom.
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.
From http://maven.apache.org/pom.html#Plugin%5FManagement
Copied from :
Maven2 - problem with pluginManagement and parent-child relationship
<pluginManagement> just like <dependencyManagement> are both used to share only the configuration between a parent and it's sub-modules.
For that we define the dependencie's and plugin's common configurations in the parent project and then we only have to declare the dependency/plugin in the sub-modules to use it, without having to define a configuration for it (i.e version or execution, goals, etc). Though this does not prevent us from overriding the configuration in the submodule.
In contrast <dependencies> and <plugins> are inherited along with their configurations and should not be redeclared in the sub-modules, otherwise a conflict would occur.
How does/should Maven plugins behave with regards to the order in which they process configuration options? I would expect that properties passed via CLI overwrite those defined in a <configuration> block in pom.xml.
Here's an example.
pom.xml
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<version>1.2.3</version>
<executions>
...
</executions>
<configuration>
<url>foo.com</url>
</configuration>
</plugin>
CLI
mvn group:artifact:1.2.3:doit -Dmymojo.url=bar.com
I am currently debugging a plugin (not mine) that gives precedence to the url value defined in the POM rather than the one passed on the CLI. Is that how mojos are supposed to behave i.e. a Maven feature rather than a plugin bug? I didn't find anything mentioned in the ref guide.
As per https://issues.apache.org/jira/browse/MNG-4979 this works as designed. I find it counter-intuitive and don't find the reasons given in MNG-4979 convincing.
If your setup allows to modify the pom.xml you can work around this behavior as suggested by JF Meier (and the issue above).
<properties>
<mymojo.url>foo.bar</mymojo.url>
</properties>
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<version>1.2.3</version>
<executions>
...
</executions>
<configuration>
<url>${mymojo.url}</url>
</configuration>
</plugin>
Through the command line, you set a property url. This would override an entry <url>foo.com</url> in the <properties> section of the POM.
Many plugins allow to set configuration entries through properties, but these properties do not automatically have the same name. In the documentation, this is usually called user property. To see examples, look e.g. at
https://maven.apache.org/plugins/maven-dependency-plugin/get-mojo.html
I want to deploy two jar artifacts with different classifiers, but at the moment that fails because both supply their own version of pom.xml. How can I fix that, so that both pom.xmls can be uploaded along with their artifacts?
Example - I have com.test.company.somelib-1.0.0-cmp1.jar and com.test.company.somelib-1.0.0-cmp2.jar, where cmpX is a classifier. Both packages contain (logically) the same code and classes (of the same version), they only differ slightly in the way they were preprocessed. The classifier annotation is there due to backwards compatibility we need to maintain.
Long story short, first artifact uploads fine, second one fails with Forbidden, because our repository does not allow overwriting artifacts (and I want to keep it that way).
There is a slightly different pipeline that creates both the packages, so it is easier to have their builds separate. I just want to deploy them as two packages of the same name and different classifier.
Thanks for help
Edit: it has been suggested to use Maven profiles. I can see that they would work, but they would not be ideal.
Consider the setup I have depicted on the picture below - there is a CI server (TeamCity).
There is a "starter" build (Sources). This build checkouts all required source files.
From this starter build several other builds are triggered (processing using x.x.x/compile). Each of those builds adjusts a template-pom.xml (fills in particular classifier and other info), and then builds and deploys its artifact to our Artifactory.
With the setup I want to achieve if I decide to add another processing-build, all I need to do is add another "branch". If I was using profiles, I would need to also add a new profile to the pom.xml file.
Correct me if I am wrong please. Profiles seem to be able to achieve the goal, but not ideally, at least in my case.
I strongly discourage having 2 (or more) different pom files with the same GAV.
But I understand your need is raised by legacy reasons.
I have not tried this myself but it could be working:
Leave one build (= maven project) as you have it now. On the other build skip the normal deployment and manually invoke the deploy-file goal of the deploy plugin like so:
<build>
<plugins>
<!-- skip normal execution of deploy plugin -->
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<id>default-deploy</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<!-- invoke with goal: deploy-file -->
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<id>someId</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<inherited>false</inherited>
<configuration>
<file>path-to-your-artifact-jar</file>
<generatePom>false</generatePom>
<artifactId>xxx</artifactId>
<groupId>xxx</groupId>
<version>xxx</version>
<classifier>xxx</classifier>
<packaging>xxx</packaging>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The two main approaches for enforcing maven 3 seem to be:
maven-enforcer-plugin, and
pom.xml <prerequisites> element.
The best approach to uses seems to depend on a few different factors. This question is to help people decide which approach makes the most sense for them.
Question: What types of project structures are best suited to maven-enforcer-plugin and what types of project structure are best suited to pom prerequisites.
Maven Enforcer Plugin Example
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>enforce-maven-3</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.0.5</version>
</requireMavenVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven POM Prerequisites Example
<project>
...
<prerequisites>
<maven>3.0.5</maven>
</prerequisites>
...
</project>
Prerequisites are deprecated, and you should use the enforcer plugin. MNG-5297 requests a documentation update to clarify this.
The maven-enforcer-plugin FAQ explains the difference:
Why can't I just use the prerequisites tag in the pom?
The prerequisites tag was designed to be used by tools like plugins. It will work for regular projects, but it isn't inherited to their children. If it is set in a parent reactor, then Maven will do the check. However if one of the children are built, the check is not performed. The enforcer plugin is designed to allow centralized control over the build environment from a single "super-pom", and to allow greater flexibility in version specification by supporting ranges.
In addition, note that prerequisites do not work with Maven 3.
The Maven pom prerequisites approach may be more appropriate for smaller, simpler projects. This approach will be lighter weight as it will not require the maven-enforcer-plugin to be downloaded.
The maven-enforcer-plugin approach may be more suitable if you have children projects that you wish to inherit the maven 3 requirement from the parent. pom prerequisites is not inherited by children projects.