locking snapshot versions when depending on multi-module project - maven

I have a multi-module project (B) that depends on various modules of another multi-module project (A). Each module of (B) might depend on different parts of (A), but they should all use the same version of (A). Current that version is specified as a property in the parent pom of (B).
I would like be able to lock the version used to a specific build (x.y.z-ts-buildnum) from a single command while keeping the version of (B) to use listed only once.
In parent:
<dep.version>4.1.0-SNAPSHOT</dep.version>
In a module:
<dependency>
<groupId>com.example</groupId>
<artifactId>B-foo</artifactId>
<version>${dep.version}</version>
</dependency>
I tried:
versions:lock-snapshots but that does not seem to lock versions set by properties
versions:update-properties which is for updating property versions but not locking snapshots
Writing a script around resolving the latests snapshot of A's pom from the local repository, but that does not work because each module has it's own timestamp. I could write a script to look at every module, but that's getting close to the amount of work a maven plugin would do.

I would suggest to define the dependencies to your module-A in your parent of the module-b like this:
<properties>
<module-a.version>6.5.0-12-SNAPSHOT</module-b.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>A-foo</artifactId>
<version>${module-a.version}</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>A-bar</artifactId>
<version>${module-a.version}</version>
</dependency>
...
</dependencies>
</dependencyManagement>
Within your modules you now only need to write:
<dependency>
<groupId>com.example</groupId>
<artifactId>A-bar</artifactId>
</dependency>
which will give you the possibility to change the version of all modules only within a single place. At the root of your module-A.

Related

Maven copy parents declared in the POMs

My final goal is to create a Maven repository in a certain directory containing only a certain set of artifacts and all their dependencies.
For this I use the following command:
mvn.bat dependency:copy-dependencies -f dependencies.pom
-DoutputDirectory=localRepoDir -Dmdep.useRepositoryLayout=true
-Dmdep.copyPom=true -Dmdep.addParentPoms=true
dependencies.pom being:
<project>
<modelVersion>4.0.0</modelVersion>
<description>Dependencies</description>
<groupId>com.dummy</groupId>
<artifactId>dummy</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.dependency1</groupId>
<artifactId>dep1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.dependency2</groupId>
<artifactId>dep2</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
When doing this, I notice that parents declared in the dependencies' poms are not copied from the .m2 Local maven repository to the destination directory.
Perhaps I'm missing something and there's a better way to do this, since it's kind of a hack to use a pom file to declare the artifacts I want to copy (together with their dependencies).
Turns out that maven was using version 2.8 as default for the dependency plugin. When explicitly indicating it to use the latest version (2.10), it worked just fine.
The addParentPoms parameter was already introduced on 2.8 for copy-dependencies, so I guess it must be a bug in the 2.8 release.
mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:copy-dependencies

Update pom to use released versions

Trying to find a way to update a pom to use latest versions of a RELEASED dependency instead of SNAPSHOT.
We have a assembly project that assembles an image to be deployed that during development uses SNAPSHOT dependencies.
But now I want to update the dependencies to use the latest released dependencies. Tried using versions:use-latest-releases but it only affects already released versions in the pom.
Any ideas?
EDIT (can not for security reasons post the pom but here's an example)
<project>
....
<dependencies>
<dependency>
<groupId>a.b.c</groupId>
<artifactId>c-d-f</artifactId>
<version>1.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>a.b.c</groupId>
<artifactId>g-h-i</artifactId>
<version>1.1.6-SNAPSHOT</version>
<type>war</type>
</dependency>
...
</dependencies>
...
</project>
Given that component a-b-c and g-h-i has been released with version 1.0.1 and 1.1.6 I want to replace their versions in this pom with these version numbers. Basically remove any snapshot dependencies in the pom.
EDIT
I should add that is to be an automated process with minimal human interaction. For some reason I can only get versions:update-properties to work if versions are already in release state. If I have a snapshot version 0.0.1-SNAPSHOT and want to update it to 0.0.1 it doesn't happen and I have verified the release exists. Same thing with versions:use-latest-relese, and versions:use-releases does nothing at all.
I see two approaches here:
You can create multiple profiles in your maven pom. Best way is to create a profile of "snapshot" and one for "release". Described here: Different dependencies for different build profiles in maven
You can use maven pom properties to define variables for your dependency versions. See here: http://books.sonatype.com/mvnref-book/reference/resource-filtering-sect-properties.html#resource-filtering-sect-user-defined
Hope that helps!
You can use maven properties in your pom.xml, such as:
<properties>
<c-d-f.version>1.0.1-SNAPSHOT</c-d-f.version>
<g-h-i.version>1.1.6-SNAPSHOT</g-h-i.version>
</properties>
<dependencies>
<dependency>
<groupId>a.b.c</groupId>
<artifactId>c-d-f</artifactId>
<version>${c-d-f.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>a.b.c</groupId>
<artifactId>g-h-i</artifactId>
<version>${g-h-i.version}</version>
<type>war</type>
</dependency>
...
</dependencies>
and when you want to change the versions, you can use maven-versions-plugin, with the following command, such as:
versions:update-properties -Dproperties=[${release_version}] -DincludeProperties={c-d-f.version}
EDIT:
Note that if you wanna use SNAPSHOTS, you need to add -DallowSnapshots. Read here for more options. And yes, the version needs to exist in the repo, otherwise it will fail. BTW did you use brackets, such as -Dproperties=[0.0.1]? after you read the link I sent you, you will see that this commmand's input is a range, so you must use brackets in order to specify a unique version.

Set Maven dependency versions in properties file

We have a couple of different applications which may or may not interact together. When they interact together, there have been issues because of mismatch in third party library versions (Let it be Spring or something else).
The pom files for these applications are separate, but to solve the above issue, we want them to use the same versions of third party libraries. The easiest way to do this is to specify the versions in common properties file, and then let respective pom.xml read the versions from the properties file.
Usually I am used to specify the versions as properties in the parent pom, and let the module pom read it from there. Is there a way I can make pom.xml read the properties file for reading the versions?
Some projects, e.g. spring-cloud and spring-boot, express their 'release train' (a set of dependencies and their versions that are known to work well together) in a 'BOM' (bill of materials). The BOM is nothing but a POM with only a dependencyManagement section, where all these dependencies are listed with the correct version. That BOM is then included in each project's POM that should follow these dependencies/versions in its dependencyManagement section, with scope 'import'.
E.g.
You create your separate project 'my-bom', containing only a pom like this:
<project>
<groupId>your.organication.program</groupId>
<artifactId>my-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.whatever</groupId>
<artifactId>somedependency</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.whatever</groupId>
<artifactId>someotherdependency</artifactId>
<version>4.5.6</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
And then you include that in each project that should be aligned with these dependencies/versions:
groupId>your.organication.program.project</groupId>
<artifactId>some-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.organisation.program</groupId>
<artifactId>my-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencyManagement>
Within the projects the dependencies that are effectively used must still be referenced in dependencies-section, but without the version - the versions are managed by the BOM.

How do I default sub-module versions in a Maven multi-module project using snapshots?

I looked at previous questions on the topic and it seems people were a step ahead of where am I at the moment.
I am currently trying to use the maven release plugin to my multi module project. I start from scratch (more exactly, I retrieved some old projects to put in a new multi module project).
I have a POM parent that I defines as:
<groupId>com.somestuff</groupId>
<artifactId>stuff</artifactId>
<version>10.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name> stuff </name>
My child modules inherits the parent using:
<parent>
<groupId>com.somestuff</groupId>
<artifactId>stuff</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
So since it’s a new project, I specify the dependencies between modules as snapshots. For example, if module A depends on module B, I will add to A’s POM the part:
<dependencies>
<dependency>
<groupId>com.somestuff</groupId>
<artifactId>divarmiclient</artifactId>
<version>10.0.0-SNAPSHOT </version>
</dependency>
</dependencies>
The result is when I try to do a “mvn release:prepare”, Maven will yell that there is snapshot dependencies. But since it’s a whole new project, and that versions prior to 10 don’t exist, I have no idea how to default the version values of the modules.
My question is, how shall I default the module values ? How do I do in order to make my multi-module project acceptable from a snapshot perspective ?
For clarification, you're saying your structure is:
theparent
pom.xml
A/
pom.xml
B/
pom.xml
And the following assumptions all hold true:
theparent, A, and B are currently on same version
releases will always be kicked off from 'theparent' level so they remain on same version
A depends on B, always same version
Then the solution is as follows:
<dependency>
<groupId>com.somestuff</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
</dependency>

How to reference a parent project from a child

I have a multi module project like this:
gwt-app
model
webapp (depends on gwt-app and model)
when I try to execute any goals in webapps, for example, launch jetty, build fails because maven can't find its dependencies (I didn't install modules into a local repo). Is there a possible way to reference the parent pom so that when I run any goals in a submodule, all its dependencies will be compiled (recompiled)?
An example of your pom files would be great but in multi module projects I always declare the dependencies in the parent pom in the dependencyManagement tag:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
...
In the module pom I just delcare the dependency without the version:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
...
That way were are sure each module uses the same version.
The thing to remember is that modules in maven do not inherit dependencies from the parent. You must declare the dependencies used in the module itself.
Another thing is, I believe that when you are running outside of an IDE (which searches the workspace for dependencies) you need to have each module installed in your local repo. I do not think maven will search for un-installed dependencies within a multi module project if you are not executing on the parent pom.
If you make your parent pom just have regular setup like
<plugins>
</plugins>
<dependencies>
</dependencies>
Then anything in those groups are inherited automatically into the child pom. Child pom just needs the parent section in it:
<parent>
</parent>
You don't even need to declare the same plugins or dependencies in the child pom in this manner. You only need to list the plugins or dependencies in the child pom IF you use or in the parent pom OR you want to override something in the parent pom. I actually just went through all of this week and have my builds working nicely now (small child poms with more things in the parent pom like plugin configurations).
I asked a question about this that might help you:
Maven - Parent Pom - Child Inheritance

Resources