Release a lightweight maven POM - maven

I have a multi-module project that I'd like to consolidate when I release. More specifically, I'd like to have my release POM be a separate lighter version of the POM I use for builds.
Is it possible to have or create a separate POM for releases?

There's nothing preventing you from putting two poms in a project. If you were to add a second one called pom-release.xml, then you could invoke that pom using
mvn -f pom-release.xml <phases and goals>

Related

Updating the versions in a Maven multi-module project

I have Maven multi-module project and I would like to update the development versions to a given value using a script. The aggregator POM is only an aggregator and the children do not inherit from it. This is important because the artifacts all inherit from other POM files. Here is my structure
aggregator/
--projectA
--projectB
Also, projectB has a Maven dependency on projectA.
First I tried:
mvn -DnewVersion=0.28-SNAPSHOT -DupdateMatchingVersions=true versions:set
It only updated the aggregator project's version.
If I run the Maven release process, it correctly updates projectB's dependency on projectA to use the new development version after the release build. Because the release process handles this well, I thought that using the release plugin might solve my issue.
So I tried the following:
mvn -DdevelopmentVersion=0.28-SNAPSHOT -DautoVersionSubmodules=true --batch-mode release:update-versions
This updated all of my sub-projects correctly. However it did not update projectB's dependency version for projectA.
What is a simple way to update all the development versions in my project, including projectB's dependency on projectA?
You may have more luck with the release plugin but it may require some tweaking
versions:set is designed to update the version of the pom that it executes against... ie the root of the reactor.
If you follow it's conventions, then it will work... But you need to know its conventions.
When you have /project/parent/version and /project/version both specified but "accidentally" at the same value, the versions plugin assumes that the two versions are just accidentally the same, and so does not update the child project's version when the parent version is being updated. updateMatchingVersions tells the plugin to assume that it us not an accident and that the child should be in lock step.
If you only specify /project/parent/version and leave the project version unspecified, therefore relying on inheritance, the plugin will add the child project to the list of version changes (and hence loop through all the projects again to ensure it catches any additional required changes)
The versions plugin does not currently provide an option to force everything to the one version... Though that might be a good idea.
You can get what you want with three commands, eg
mvn versions:set -DnewVersion=...
cd projectA
mvn versions:set -DnewVersion=...
cd ../projectB
mvn versions:set -DnewVersion=...
This is because versions:set will attempt to "grow" the reactor if the parent directory contains an aggregator pom that references the invoked project...
In other words when you have a reactor with no common parent, versions assumes that the common version number is by accident, but it will pick up the intent from the wider reactor
# for each module into aggregator pom
for module in $(grep "\<module\>" pom.xml | sed 's/<\/module>//g' | sed 's/.*<module>//g' | sed 's/.*\///g')
do
# set the version of the module
# and update reference to this module into others modules
mvn versions:set -DgenerateBackupPoms=false -DartifactId=$module \
-DnewVersion=$newVersion -DupdateMatchingVersions=true
done
# set the version of the aggregator pom
mvn versions:set versions:commit -DnewVersion=$newVersion
i found your same problem ,then i clone versions plugin code , then I found if you set gropuId,artifcatId,oldVersion value tobe * will solve the problem;
like this :
mvn versions:set -DnewVersion=xxx -DgroupId=* -DartifactId=* -DoldVersion=*

parameterise POM file (Maven)

Whenever I want to create a new version of my projects, I have to go in and edit the <version> tag in the POM files.
The projects are related, so they have the same version, most of the time.
Is it possible to just put the new version in some file, and have the POM regenerated when needed?
Thanks
The best thing in such situations is to use the release plugin which supports automatically changing the version in the pom and creating a tag/label in the appropriate VCS. There are two steps release:prepare and release:perform which can simply be combined.
A command like this:
mvn release:prepare release:prepare
will do all needed steps like making a tag in VCS, change pom's version and deploy the artifacts to your repository. But the prerequesite is having correct entries in the SCM area of your pom, correctly configured the distributionManagement etc.
If the project comprises of several modules which have the same version this sounds like using a multi-module build instead of separated projects which would solve the problem of changing the version manually.

Maven uses different timestamps when building snapshot artifacts in a large project

We have a large maven 3 project with around 250 modules. All modules have version 1.0-SNAPSHOT and modules tree has single parent module with the same version as a tree root.
Project is built with Bamboo nightly and artifacts are installed to a Nexus repository using command "mvn clean install".
It happens that part of modules are built with one timestamp while the rest with the other, something like:
module1-1.0-20121127.150154-7.jar
module100-1.0-20121127.150527-7.jar
In another project I was trying to set dependency to artifacts of this project using specific version of a snapshot dependency (as discussed in this question Maven specific version of a snapshot dependency) but failed to build due to the problem described above.
Does anyone know why maven would use different timestamps and how to fix that?
MNG-6754 was finally fixed in 3.8.2.

How to rebuild dependencies before running jetty from maven

I have a multi module maven project. One of the modules is a reusable part which is packaged into a jar, and the other is a war web-app which depends on the first module. When I use jetty:run-exploded on the second module, the packaged jar is taken from local maven repository whereas I want the first module to be rebuild and packaged into the resulting war. Is there any way to force such behavior instead of the default one?
From everything I can tell from reading documents about Maven's design and using Maven myself this cannot be done in the projects own directory.
Maven will not follow module paths UP a hierarchy. Using -amd (also make dependencies) will only work at the top level module that ties all the other multi-module pom's together. So what you can do is this:
At the TOP level directory
mvn -amd -pl jetty_module jetty:run-exploded
I think you can use maven Advanced Reactor Options to archive this.
http://www.sonatype.com/people/2009/10/maven-tips-and-tricks-advanced-reactor-options/
The -pl or –projects option allows you to select a list of projects from a multimodule project. This option can be useful if you are working on a specific set of projects, and you’d rather not wait through a full build of a multi-module project during a development cycle.
Maven -amd(also-make-dependents ) also help to build multi module project once. Using that you can build a project and any project that depends on that project.

Why does maven recognize dependencies on only installed POM files?

I've got a project with Maven in which one subproject (A) wants to depend on another subproject (B) which uses "pom" packaging.
If I do this the straightforward way, where A specifies a dependency on B with <type>pom</type>, things work perfectly if I do "mvn install", but if I run any phase earlier than install, such as mvn compile or mvn package, then it fails while trying to build A: it goes looking for B's pom in the repository, and doesn't find it.
I don't really want this pom in the repository, because it's part of our active source code and changes frequently.
For all the jar-packaged projects we build, it seems to work fine to keep them out of the repository, build with mvn package, and Maven knows how to find all the dependencies in the source and build trees it manages without resorting to the repository; however for the pom-packaged project it always wants to go to the repository.
A couple things I learned while trying to understand this:
Maven best practices encourage you to use pom-packaged projects to group dependencies, but with the added step of "mvn install" on the POM project
Maven lifecycle documentation says "a project that is purely metadata (packaging value is pom) only binds goals to the install and deploy phases"; maybe this is why the POM project is invisible as a dependency target unless I invoke the install phase? I tried binding the compiler plugin to the compile phase and this didn't seem to help.
Is there a way that I can specify the POM subproject as a dependency of another subproject in the same parent project, without installing the POM project to the repository?
It isn't purely a question of which goals are bound to which lifecycle phases for POM projects. If it were, then binding the "package" goal would solve the problem.
When building a multi-module project, Maven reads the POMs of all modules to determine dependencies between modules, so that it can build the depended-upon modules before the depending modules. It's able to achieve this even when running the "package" goal (such that the depended-upon modules are not yet in the local repository).
Therefore, the code that constructs the classpath for builds must be managing several cases, notably:
extra-project jar dependency, where it looks for the POM in the local repository, handles its dependencies, and adds the POM's jar to the classpath
extra-project pom dependency, where it looks for the POM in the local repository and handles its dependencies
intra-project jar dependency, where it looks for the POM within the project tree, handles its dependencies, and adds that module's target/classes folder to the classpath
intra-project pom dependency, where for some reason it doesn't look for the POM within the project tree, and therefore doesn't handle it's dependencies.
Notice the asymmetry in the last two cases, as compared to the first two.
I can see two solutions to your problem. One is to file a bug report, or rather a request to change the behaviour (since it's obviously intentional), perhaps only for the case of intra-project dependencies on multi-module projects. Or indeed propose a patch. But since the behaviour is intentional, you might meet a refusal. In the best of cases, you're in for a long wait. (I'd vote for your bug report though - I've been stung by that same behaviour, in a different context.)
The other solution is simply to run an install on your project. I don't really understand why you don't want the POM project in your repository: if needs be, you can use a snapshot repository, where it doesn't matter if things change frequently, to avoid polluting your main repository.
Configuring maven-install-plugin to run during the compile phase, and copy the relevant pom.xml to the repository, seems to accomplish what I wanted as far as Maven itself is concerned, though m2eclipse still is not happy (it throws "failed to read artifact descriptor" errors with no additional description for the pom.xml that has a dependency on the other POM project).

Resources