maven: parent-version - maven

I don't understand what is the parent version and for what it should be good?
We use svn in our team and when I did update for the project the last time I notcied that the parent version is changed:
local pom.xml
<parent>
<artifactId>foo</artifactId>
<groupId>bar</groupId>
<version>0.42-SNAPSHOT</version>
</parent>
svn pom.xml
<parent>
<artifactId>foo</artifactId>
<groupId>bar</groupId>
<version>0.45-SNAPSHOT</version>
</parent>
When does parent version change and for what it should be good?

A parent POM contain settings that apply to all child modules. This may include declaring plugin settings or choosing dependency versions.
A parent POM is no different to any other Maven artifact. It can change and when it does the version number must increment. Typically you want to always be using the latest available version of your parent.
You can use the Maven versions plugin to help manage versions, including forcing an update to the latest available parent version.

Parent pom and child pom come into picture if you have a multi-module project. For example like the below
/myapp
|- pom.xml --> parent pom
|+ module1/
| - pom.xml --> child pom
| - src/
|- module2/
There can be several such hierarchies. There are 2 ways to define this inheritance
Add a xml block in parent pom to tell it which are the dependent modules. OR
Add a xml block in a module to tell whose is it's parent. (This is your case)
This means that, the child pom is dependent on parent and will try to find the the concerned artifact with 0.45-SNAPSHOT version. This version has changed probably due to a newer build of parent has taken place replacing the version.

Related

Dependency Management in AEM project POMs

In AEM project poms I have noticed that dependency name and versions are defined in the parent pom and it is not necessary to specify a version in child poms, as the version is managed at the Parent pom. And child poms only have dependencies defined. So, I am not clear on following.
1.If we already have dependencies defined in the parent pom with version no, then why do we need to define the same dependency back in child pom.xml (core/pom.xml in case of AEM).
In Maven there is a difference between <dependencies> and <dependencyManagement>. Only the former really adds dependencies to your project, while the latter only defines the preferred version numbers (and scopes).

maven module build. Not specifying version with children modules

We have a multi-module build. I have a parent module that builds 17 other modules and one of those modules itself is another multi-module build that builds three others.
In my parent module:
<groupId>com.veggicorp.foobar</groupId>
<artifactId>foobar-parent</artifactId>
<version>5.4.3</version>
<properties>
<!-- Definition of versions for third party jars -->
</properties>
<dependencyManagement>
<!-- Another way to specify dependencies throughout the project -->
</dependencyManagement>
<modules>
<!-- List o' Modules -->
</modules>
By using properties to specify versions (and using dependencyManagement), I found I can get rid of almost any sort of version numbering in the child modules. This makes it very simple to maintain a complex project since most of the changes will take place in the parent. When we do a new version, I don't have to update 21 other pom.xml files.
However, there is one sore spot: I have to specify the parent version:
<parent>
<groupId>com.veggicorp.foobar</groupId>
<artifactId>foobar-parent</artifactId>
<version>5.4.3</version> <!-- Must Specify -->
</parent>
<artifactId>foo-server</artifactId>
<!-- No need for a version -->
<build>
....
Note that I don't need to specify the version of the child. It takes the parent's version by default. However, I have to fill in the parent's version number despite the fact that all of this sits in a single Git repository, and that all of the modules are unique for this project and are not used anywhere else. We won't even be deploying these modules' jars to our Maven repository. It's one big gigantic build.
I know I can use the version plugin to update all of these modules, but that means our developers must remember to use that plugin when they create a new version of the project. (I don't have much faith in our developers. Heck, we have directions on our wiki on how to tie your shoes.)
So, is there a way where our child modules -- which get checkedout with the parent module in a single big Git repo -- can avoid having the parent version number embedded in them?
The answer is no, you have to include the parent information in all the child modules and that information has to include the version.
However once you have set this up you can use the versions plugin to mange the versions of all your poms see http://www.mojohaus.org/versions-maven-plugin/
example, from the top level:
mvn versions:set -DnewVersion=1.1
will change all the children and the parent.

Does incrementing depending module version should increment parent module version?

I have parent module A that has module B as its dependency. If I increment version of B for just a simple bug fix, that does not change any API or break anything, do I still need to increment version of A?
Example:
A:1.10.0 --> B:2.5.0
fixing B to 2.5.1
In this case, A on Maven depends on older version of B, therefore, it seems it make sense to increate the version of A, too; so to have:
A:1.10.1 --> B:2.5.1
even though we didnt change anything in A.
Is this correct?
Yes, you are correct. If you change version of any of the dependency, you will need to build and release parent project again. This will create the new released version of your parent module A.
(Here, I am assuming that parent module A packaging type is other than pom. If the packaging type is pom, then its a different story altogether.)
Edited:
When you say parent project, you will declare its packaging as pom. It will have it's own version.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>web-project</module>
</modules>
</project>
You can also refer to some modules (child projects) in your parent pom declaration.
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>web-project</artifactId>
<packaging>war</packaging>
Then for submodules there is no need to declare any version for it. Parent version will be carried over to the child project. You can override version in the child project but that's not a common practice. So your parent pom version will be incremented automatically when you release it with maven. And this new version will be carried over to child projects (modules) also.
See this - Maven project version inheritance - do I have to specify the parent version?
So parent module A, I was referring to the above case.
And maven repo - can be of two types - local repository and remote repository. Local repo is where maven looks for resolviing dependencies. This is on your machine. If maven doesn't find it there, maven retrieve those depedencies from remote repository.

Maven - How/Why/Should it work to set the parent version to be based on a property defined in the parent pom?

I have the following POM structures:
/home/projects/parent/pom.xml
<project>
<groupId>com.my.group</groupId>
<artifactId>project-super-parent</artifactId>
<version>${major.version}.${minor.version}</version>
<packaging>pom</packaging>
<properties>
<major.version>7</major.version>
<minor.version>5</minor.version>
<current.release.version>${major.version}.${minor.version}-SNAPSHOT</current.release.version>
...
</properties>
....
</project>
/home/projects/module1/pom.xml
<project>
<groupId>com.my.group</groupId>
<artifactId>module1</artifactId>
<version>${current.release.version}</version>
<packaging>jar</packaging>
<parent>
<groupId>com.my.group</groupId>
<artifactId>project-super-parent</artifactId>
<version>${major.version}.${minor.version}</version>
<relativePath>../parent</relativePath>
</parent>
...
</project>
Notice that the module does not know the version of it's parent - it uses a property defined in the parent, so this is a kind of a chicken & an egg problem.
The weird thing is - that this works - so when I want to change the major version of the product - I only change a single pom file (the parent).
The limitations to this solution is that I have to have all POM files on the file system.
My questions are: should this even work? How exactly does it work? Is it likely to stop working when I upgrade to maven 3? Is this a commonly used solution or an abuse of the system?
Currently using Maven 2.2.1 and Java 7.
Is this a commonly used solution or an abuse of the system?
That is not common, at least I have never seen it before. The versioning you have in parent/pom.xml and module1/pom.xml will cause a confusion. The parent has a RELEASED version of 7.5, while module1 has a SNAPSHOT version of 7.5. You should not be developing 7.5-SNAPSHOT if 7.5 is already released.
The simplest way to avoid duplication is to maintain the version only in the parent. You can just omit the version declaration in module1. Take a look another project, e.g. maven-3 source code for example. You will be able to see the the version is only declared in the parent pom, and not in any of its child poms.
maven-release-plugin will help you handle the version upgrade and release them for you.
Omitting the version element from the child pom gives error.
Property can be used in Main pom and the same can be inherited by child pom's. When you run the Main pom, build will result in success. Problems are
That you can not build the child pom independently
This does not work in case of transitive dependencies
if you upgrade to Maven 3 in future than it will give error "Non-resolvable parent pom
These problems can be resolved if we are able to update the project pom file as part of the build process before it gets installed in local repository

Maven - Access properties on parent pom from a child pom

In a multi module project structure as
myApp
|-moduleA
|---pom.xml
|-moduleB
|---pom.xml
|-pom.xml
If i have the following properties in the parent.pom
<properties>
<moduleA.version>4.67</moduleA.version>
<moduleB.version>4.68</moduleB.version>
</properties>
How can i access the properties in the parent pom from any of the child poms? I tried this on the child pom but it didnt work.
<groupId>com.test</groupId>
<artifactId>moduleA</artifactId>
<version>${moduleA.version}</version>
If you have a real multi-module build you should never define the modules to have different versions. They should have the same version which make releasing possible and other things as well. Otherwise you should not use the multi-module setup than use simple single modules which are separated.
This should work. One possible reason I can think of is that perhaps you don't actually inherit the pom where these properties are defined (i.e. it's not defined as your <parent> directly or indirectly), but you only have a main pom that aggregates your projects. It's a guess, though.

Resources