Details
-
Type:
Wish
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 2.0.3
-
Fix Version/s: 3.1.1
-
Component/s: Inheritance and Interpolation, POM, Reactor and workspace
-
Labels:None
-
Complexity:Intermediate
-
Number of attachments :8
Description
It would be great if Maven supports version ranges when specifying parent artifacts in a multi-module build. Currently this does not work.
<parent>
<artifactId>artifactId</artifactId>
<groupId>groupId</groupId>
<version>[2.0, 2.0.1]</version>
</parent>
[INFO] Scanning for projects...
Downloading: [2.0, 2.0.1]/artifactId-[2.0, 2.0.1].pom" class="external-link">http://repo1.maven.org/maven2/groupId/artifactId/[2.0, 2.0.1]/artifactId-[2.0, 2.0.1].pom
Additionally it would be great if this
<parent>
<artifactId>artifactId</artifactId>
<groupId>groupId</groupId>
<version>[2.0, $
</parent>
[INFO] Scanning for projects...
Downloading: http://repo1.maven.org/maven2/groupId/artifactId/[2.0, ${pom.version}
]/artifactId-[2.0, $
{pom.version}].pom
would also work, if the version is specified in the same pom.xml which defines this parent definition.
-
- MNG-2199.patch
- 19/Nov/12 4:57 PM
- 24 kB
- Christian Schulte
-
- MNG-2199.patch
- 23/Oct/12 12:22 PM
- 23 kB
- Christian Schulte
-
- MNG-2199.patch
- 19/Sep/12 1:44 AM
- 16 kB
- Christian Schulte
-
- MNG-2199.patch
- 18/Sep/12 11:39 AM
- 16 kB
- Christian Schulte
-
- MNG-2199.patch
- 18/Sep/12 4:01 AM
- 16 kB
- Christian Schulte
-
- MNG-2199.patch
- 18/Sep/12 3:04 AM
- 10 kB
- Christian Schulte
-
- MNG-2199-3.0.4.patch
- 19/Nov/12 4:57 PM
- 23 kB
- Christian Schulte
-
- MNG-2199-3.0.4.patch
- 23/Oct/12 12:26 PM
- 22 kB
- Christian Schulte
Issue Links
- relates to
-
MNG-624
automatic parent versioning
-
Activity
It makes no sense imho that you cannot set a version range for the parent as you can with any other (regular) dependency. I would like the option to let my artifact lift on the latest version of the parent instead of linking it strictly to a specific version of the parent.
+1
The parent should be handled exactly the same way than other dependencies. Increasing manually all children's poms everytime a new reporting option has been set in the parent is not very handy. Same for release configuration, license handling , etc... in all these cases I would like the children projects to just take the latest version of the parent, or range [X.X.0,X.X+1.0) for example.
I think there is an acceptable alternative: Make <relativePath> pick up the maven coordinates of the parent pom automatically.
Most multi-module builds form a monolithic tree of poms that is always checked out atomically. I.e. we have a specific tree layout in the file system that has <module> for forwards links and <parent> for backlinks. If <module> does not need full maven coordinates why should parent? Imagine we can use either maven coordinates or a single <relativePath> as parent:
<parent>
<relativePath>../pom.xml</relativePath>
</parent>
Than the entire multi-module project can have a single groupId and version set in the root pom. We would be able to control the common version of this logical set of artifacts from one file - no more need to edit dozens of <parent> clauses for every trivial change. All that is needed is for Maven to replace <relativePath> with the actual maven coordinates when we install/deploy.
For that matter why don't we make <module> accept a set of maven coordinates as well? Than both the forward and backward links would support two modes: maven coordinates and the repo or local file system and automatic maven coordinate interpolation upon install/deploy.
Don't agree with Todor. Using relative path is not a solution since lots of projects have a (company wide) parent pom but are not part of a multi-module project.
As Sylvain said version ranges would be very handy when changing release configuration, license, etc and those are exactly the kind of things you want to configure globally for all company projects. All clients I have worked for have their own main pom in which they define this kind of things. Now, when a new version of that main pom is released, it's a nightmare to change all poms that use it directly and indirectly.
So for me a +1 for this issue.
I can agree with Joost den Boer. And it becomes more complex if you have not only one master pom but rather a few like special master poms for differend types of projects.
We also need this issue to be resolved - actually MNG-624 (no version = use latest parent) is not enough from my point of view. We need this parent POM for environmental settings (where are repositories and such) which always needs to be up to date. But: We also need to build old projects with this parent POM - and to allow to refactor the property names for example some day we need to have a rule like: In each major version of the parent POM its "API" (i. e.: the property names) stay the same.
Up to now we used settings.xml for this which we handed over through the invoker-plugin. The settings.xml were downloaded and unpacked as dependency - which of course supports version ranges. But the invoker-plugin poses other problems so that it is not a solution for us anylonger.
This is a feature I would like to have as well. In my case I would like to see the "imported" dependencies to work with version ranges.
It would be very helpful to have a support for specifying parent artifacts version by a property.
<parent>
<artifactId>artifactId</artifactId>
<groupId>groupId</groupId>
<version>$
</version>
</parent>
This feature opens a possibility to create real centralized dependency management system for multi-project enviroment.
All dependency versions can be keep as parameters (with names in some convention) in special parent project.
Each project defines versions of their dependencies with such a parameters.
Something like this:
<dependency>
<artifactId>artifactId</artifactId>
<groupId>groupId</groupId>
<version>$
</version>
</dependency>
Then, just by changing value of pom.version, we can automatically change a whole calasspath of all project in the system.
It is very helpful for managing backward compatibility changes.
Of course, the parent project is subject to the normal versioning, it's version changes each time when the new version of some project appear.
+ on on wontfix as well. Any non-determinism in parent coordinates makes repository content fluid which is a bad thing IMHO.
6 years after creating this issue, I still think it would be helpful to have this supported. For example:
The server name of a repository changes.
=> All POMs of all artifacts in the repository are broken and point to a non-existing repository.
=> need to re-release all artifacts
=> new artifact versions
=> everyone must update everything
=> at least one full release-cycle wasted
One might say that this kind of problem can be avoided by not adding repositories to the POM. If you think about that, this just ends in every environmental property being moved out into settings.xml or somewhere else. That just leads to non-determinism as well.
Executing 'mvn release:prepare' on a years old tag should work without touching anything else. It would be non-determinism if this would stop working a few years later, no ?
The version range is very important here due to the ability to declare an upper bound. I am not requesting to 'just use the latest parent' but to use the latest parent from a range (of compatible parent POMs).
During model building, if a POM contains a 'parent' element using a version range:
=>validate that range has an upper bound and fail the build if unbounded
=>load the latest parent from that range
=>validate the latest parent does not define any 'modules' - fail the build if it does (maybe use some other information to validate the POM here - a new packaging used to flag a POM to be used that way e.g.)
=>use that parent
Another example. Consider I have been using a parent POM containing the following information.
<license>
<name>GNU GENERAL PUBLIC LICENSE</name>
<url>http://www.gnu.org/copyleft/gpl.txt</url>
<distribution>repo</distribution>
</license>
As you may know, the content that URL points at changed from GPL 2.1 to GPL 3 a few years ago. If I want already deployed artifacts to stay at GPL 2.1, I cannot do anything about it. Releasing a new parent for all those artifacts would let me deal with this. Note that for this example I would want this feature to keep the artifacts from silently changing the referenced license text.
Not putting that URL into the POM would have avoided the situation, of course. You cannot predict the future, however.
I don't think parent versions should act like dependency versions. The parent should be a known quantity and not subject to environmental changes.
Updated the patch one more time. This patch adds support for
<parent> <groupId>gid</groupId> <artifactId>aid</artifactId> <version>Maven version range syntax, e.g. [1.0, 2.0)</version> </parent>
It will fail the build whenever a child references a parent that way without defining a version. Error message would be: 'Child POM gid:aid:[unknown-version] cannot inherit version [1.0,2.0) from parent. Must define a version explicitly.'
One thing I would want this patch to do additionally, is validation of the version ranges in use. I did not find methods at interface 'org.sonatype.aether.version.VersionRange' to allow querying for 'isBounded' / 'isUpperBounded' / 'isLowerBounded' which would be needed for this.
Updated the patch to additionally validate a 'version' to not use expressions.
Script started on Wed Sep 19 08:32:30 2012
$ cat pom.xml
<project>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>[,11]</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mng2199</artifactId>
<packaging>jar</packaging>
</project>
$ mvn clean
[INFO] Scanning for projects...
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project org.apache:mng2199:11 (/tmp/mng2199/pom.xml) has 1 error
[ERROR] 'version' must be a constant. @ org.apache:mng2199:[unknown-version], /tmp/mng2199/pom.xml, line 2, column 11
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
$ ^D
Script done on Wed Sep 19 08:32:42 2012
Script started on Wed Sep 19 08:33:36 2012
$ cat pom.xml
<project>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>[,11]</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mng2199</artifactId>
<packaging>jar</packaging>
<version>1.0-${expression}-SNAPSHOT</version>
</project>
$ mvn clean
[INFO] Scanning for projects...
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project org.apache:mng2199:1.0-${expression}-SNAPSHOT (/tmp/mng2199/pom.xml) has 1 error
[ERROR] 'version' contains an expression but must be a constant. @ line 2, column 11
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
$ ^D
Script done on Wed Sep 19 08:33:47 2012
Updated patch (class 'org.apache.maven.project.MavenProject' needed updating to also allow parent version ranges.)
Updated patches to handle unavailable versions for a given range.
I believe version ranges in parent POMs should be supported, because they enable an important usage pattern of maven.
I understand the argument for keeping the parent version a fixed quantity. It makes it possible to store the build repository URL in the parent POM, thus eliminating the need for an external settings file. This makes builds self-contained and reproducible.
However, I would argue that this pattern only works well for small maven projects, because it has several implications. First, it implies that whenever the parent POM version is updated, all POMs referencing it must be updated as well with the new version. This greatly reduces the ability to do partial builds, because each time the parent changes all projects referencing it change as well. Second, assuming the parent POM contains the repository URL, it must always be checked out along with the remaining source code. In large multi-module projects developers may only check out the part of the source tree that's relevant to them. Finally, it assumes developers actually update the parent version when they make a change. If they forget to do it, CI builds that perform the deployment will fail, because the parent versions already exist. In large, loosely-coupled development organization such an assumption cannot be made.
Using version ranges in parent references along with the following usage pattern can alleviate this problem:
- store each parent version in a separate repository
- point to the parent repository in the settings file
- whenever going to an older source version, delete cached parent artifact in ./m2
Note that the parent repository URL in the settings file could be derived from the current source version to keep builds reproducible. The process can also be automated to ease the burden on developers. Furthermore, since the parent references specify ranges, the CI system can automatically append a unique (and increasing) qualifier when deploying the parent to eliminate the assumption that developers will update the parent version.
Now it could be argued that in development parent references should use snapshot versions. Apart from the fact that snapshot version have their own issues when it comes to large-scale projects, this argument would be self-contradicting in this context, since snapshots are version ranges of the form "version-[beginning of time, end of time]".
tempting to 'close - won't fix'.
Whatever parent pom is present in the local repo will be used, resulting in a different effective pom on different systems.
This'll be the cause of all sorts of problems.