Hierarchy of maven projects without scattering the version number - maven-2

If you use Maven2 as a build system for a project containing many artefacts with the same version number, you have the version of the resulting build scattered in all pom.xml. In many of them even twice - in the version tag of the artefact itself and in the version tag of the parent. Thus, you have to change and check in new versions of all pom.xml on every version switch. This is somewhat annoying, especially if you have to code for several bug fixing and a development version in parallel. Is there a way around that?
CLARIFICATION: My question is about the many versions of every single pom.xml that you get over time in your source control system that differ only by the version number of the pom and / or the version number of the parent pom. Ideally, you should only need to change the pom whenever you add a dependency or something.
For example you have a project with the artifacts foo-pom (the parent pom to all), foobar-jar, foobaz-jar and foo-war. In the first release the version is 1.0 - which appears in every pom.xml. In the second release the version is 1.1 - which again appears in every pom.xml. So you have to change every pom.xml - this is annoying if you release as often as you should.
UPDATE: If you think this is important: not having to specify the parent version is already being considered. Please go to the maven JIRA issue and vote for it to get it more noticed and more likely to be added as an enhancement in an upcoming release. You need to create/have a JIRA login for that.
There is another Stackoverflow Question that is basically about the same problem.

There's another StackOverflow thread that also covers this topic that you might want to look at.
In short, not having to specify the parent version when using inheritance is already being considered. Please go over to JIRA and give it a vote bump to get it more noticed and more likely to be added as an enhancement in an upcoming release.

I've run into similar problems while working on a large system built with Maven 2.
In my opinion, the downside of the typical multi-module structure is that all modules
have to share the same version. This is indeed annoying: even if your
next release only consists in a bugfix in foobar-jar, you need to
change the global version everywhere (be it manually or with
maven-release-plugin) and roll a new release of every component. In my case, I built various WAR/EAR applications, so my customer would ask me why I delivered a new version of both app1 and app2, when only app1 was supposed to be impacted.
The opposite approach is to manage each component as an independent
project, with its own independent version. This is more flexible as it
allows partial releases, but you now need to track all these versions
manually (know which versions your next delivery will consist in, make
sure internal dependencies are consistent, etc.). This can quickly
become a nightmare in a large application.
I've long thought about a way to combine both approaches: the flexibility of independent versions, without giving up the global coherency of the system. I tried the same approach as romaintaz, and ran into the same problem. Finally, I came up with this idea:
http://out-println.blogspot.com/2008/10/maven-modules-with-independent-versions.html.
Consider it as 'experimental', as I didn't get to try it live in the end (for non-technical reasons). But I think it would do the trick.

On my project, I have such a problem. To reduce the number of versions I define in my parent pom.xml some properties, which correspond to the versions of each module:
<properties>
<project-version>1.0.0</project-version>
<!-- Same version than the parent for the module 'commons' -->
<project-commons-version>${project-version}</project-commons-version>
<!-- A specific version for the 'business' module -->
<project-business-version>1.0.1</project-business-version>
...
And then, in the pom.xml of each module, I use these properties.
The problem is that I must clearly input the version of the parent in this pom.xml.
For example, in my business pom.xml, I have:
<project>
<modelVersion>4.0.0</modelVersion>
<!-- I must indicate the version of the parent -->
<parent>
<groupId>my.project</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
...
<dependencies>
<!-- However, in my dependencies, I use directly the properties defined in the parent's pom.xml -->
<dependency>
<groupId>my.project</groupId>
<artifactId>project-persistence</artifactId>
<version>${project-persistence-version}</version>
</dependency>
However, I really suggest that you have a look to the release plugin that will take care of modifying all the version numbers for you.

Does this article provide a solution for your problem ?
The idea is to declare the version number for the whole project as a property, namely "aversion" (pun intended), in the parent pom. The parent pom's own version number can be anything as long as it ends with "SNAPSHOT".
Child modules' version is specified via the ${aversion} property. Children's reference to their parent's version is hard coded. However, since the parent pom's version is a SNAPSHOT, child modules will see the changes in the parent pom. In particular, if the parent pom changes the value of ${aversion}, the children will see the change.
Not a perfect solution according to the comments.
And the release plugin doesn't solve the real problem: merging.
Having endless copies of the version number all over the place means lots of conflicts when bringing branches back together.
Note:
with Maven 2.0.9 (latest one - April 2008) I have simply been omitting the version element from the individual modules as they will inherit the version from their parent. This works with the groupId as well if your modules share the same groupId as their parent.

This is an idea for a possible extension of maven that would solve the problem.
Currently you have to write the a version of the artifact and of the parent pom in the pom.xml. There already is a way to give an absolute location for the parent pom:
<parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent>
If you allow omitting of both the version of the parent and of this pom iff maven is able to access the parent pom by the relative path, you are done. The version is only mentioned in the parent pom and nowhere else.

We have exactly this problem. We have a a large number (around 10) of different projects some of which depend on each other. The folder containing the projects has a parent pom for the entire set of projects. Each time we created a new branch we had to go into each and every pom file to change the <version> element and also the <version> for the parent, and all this editing was annoying.
After reading this question and the answers here I realized that the situation was hopeless. Each project could inherit the <version> element from the parent pom so that one was easy to eliminate, but we obviously could not inherit the <version> for the <parent>.
Unfortunately, I forgot to tell my colleague it was impossible, so he fixed it. His solution was to add a property to the parent pom file:
<properties><currentVersion>2.6.1-SNAPSHOT</currentVersion></properties>
Then in the child pom files we declared the parent version tag like this:
<version>${currentVersion}</version>
I don't know why this works. I don't see how it can find the right parent pom without specifying the version number. But for me (maven version 1.5.0_22) it is working.

Here is another lightweight workaround until the maven issue is resolved. In one large project we do no longer put the pom.xml itself in the version control, but a pom-template.xml which just contains a placeholder for the version number. After updating the project tree from version control you need to run a little ant script that generates the actual pom.xml in every directory. This is annoying, but less annoying than to have to put up with all those bothersome pom versions.

Related

Setting ivy conflict managers

I am trying to set conflict managers in Ivy, but I can't find a concrete example of how to set them. For example, to set the "strict" manager, what would this look like?
<conflict-managers>
???
</conflict-managers>
<rant>
Yeah, isn't Ivy documentation a hoot! I mean, does it have to be well organized and complete? Does it really have to make sense. I mean, it's not like my job depends upon it!
Wait a second, it does...
</rant>
Sorry, I have to get the state of Ivy documentation off my chest. It makes Maven documentation look wonderful in comparison.
The best book on Ivy I've found is Manning's Ant in Action. It's a seven year old book that's out of print (but is still available as an ebook. If it wasn't for this book, (which is using Ivy 1.4), I would have been completely lost. Unfortunately, it doesn't delve deep into the Ivy settings.
There is a listing of all of the possible conflict managers buried deep in the Ivy documentation.
all this conflicts manager resolve conflicts by selecting all revisions. Also called the NoConflictManager, it doesn't evict any modules.
latest-time this conflict manager selects only the 'latest' revision, latest being defined as the latest in time. Note that latest in time is costly to compute, so prefer latest-revision if you can.
latest-revision this conflict manager selects only the 'latest' revision, latest being defined by a string comparison of revisions.
latest-compatible this conflict manager selects the latest version in the conflicts which can result in a compatible set of dependencies. This means that in the end, this conflict manager does not allow any conflicts (similar to the strict conflict manager), except that it follows a best effort strategy to try to find a set of compatible modules (according to the version constraints)
strict this conflict manager throws an exception (i.e. causes a build failure) whenever a conflict is found.
I haven't played around with them, but I believe you simply do the following in the ivy-settings.xml:
<conflict-managers>
<latest-revision/>
</conflict-managers>
You can also define conflict management in your ivy.xml too which might be a bit more practical since it can be defined on a module-by-module basis.
Of course a few examples would have gone a long way with this, but the Ivy documentation doesn't provide many.
The best book on Ivy I've found is Manning's Ant in Action.
That was me. Ivy has moved on a lot since then, and so have builds
One issue with the ivy conflict managers is that it differs from maven, whose policy is "shallowest on the graph first", that picks the closest one. This is good if you explicitly ask for a version, bad if you have >1 transitive dependency when "closest" isn't what you want.
With ivy you can hit the strict resolve which says "you have to explicitly resolve every single conflict in your dependencies". This adds extra work # build time, but has a key result: if you explicitly declare the versions of things you want, you are now in control of what you have in your classpath.
The Ivy reference documentation strictly follows the XML tag structure of the ivy.xml and ivy-settings.xml files. You are expected to extract the information required directly from the document structure.
Decoding from the Ivy docs:
The conflict-managers tag is for declaring what conflict managers a project may use and configuring them if they accept configuration, not for setting the conflict manager to use.
<conflict-managers>
<latest-cm name="mylatest-conflict-manager" latest="my-latest-strategy"/>
<compatible-cm name="my-latest-compatible-conflict-manager" latest="my-latest-strategy"/>
</conflict-managers>
The settings tag has an attribute for choosing the default conflict manager:
<settings defaultConflictManager="strict"/>
Or in an ivy.xml:
<dependencies>
<dependency.../>
<conflict manager="strict">
</dependencies>
Note that most of the conflict managers are more liberal in their interpretation of your intentions than you would expect. Two examples:
* Branches are considered irrelevant, if a dependency is available on two branches the "latest" family of resolvers will pick the latest available from either.
* Both the "latest-time" and "latest-revision" resolvers ignore version constraints except to set boundaries on the matching space. e.g. if a depends on b-1.0 and c-1.0 but c-1.0 depends on b-5.0 then you will get b-5.0 despite it not meeting the constraint requested.
I assume your need is result of discovering one of these design flaws.

Does Ivy have different resolution behavior depending on status attribute?

My colleague pointed out a flaw in maintaining our artifacts (still somewhat new to Ivy):
The release builds are marked as “integration” which means it is rechecking for new versions on each build slowing down the build even when it has cached the dependencies.
That did not make much sense to me, since, I think, Ivy still needs to check what is in repo before making a decision about the version to deliver. So, I decided to research that a bit to understand exactly what are the effects of marking libraries with different status values.
I cannot find much in the documentation, though, or on the net. What am I missing?
Could someone please shed some light on this?
Thank you
The status is just a string, that can be defined for ivy. They don't affect the resolving of artifacts per se. It has no effect on the default retrieval. It's just a marker for an artifact.
Status:
Status of a revision A module's status indicates how stable a module
revision can be considered. It can be used to consolidate the status
of all the dependencies of a module, to prevent the use of an
integration revision of a dependency in the release of your module.
Three statuses are defined by default in Ivy:
integration: revisions builded by a continuous build, a nightly
build, and so on, fall in this category
milestone: revisions delivered to the public but not actually
finished fall in this category
release: a revision fully tested and labelled fall in this
category
You need to declare the dependency as changing or the resolver definition to achieve what your co-worker mentioned:
Changes in artifacts Some people, especially those coming from maven 2
land, like to use one special revision to handle often updated
modules. In maven 2 this is called a SNAPSHOT version, and some argue
that it helps save disk space to keep only one version for the high
number of intermediary builds you can make whilst developing.
Ivy supports this kind of approach with the notion of "changing
revision". A changing revision is just that: a revision for which Ivy
should consider that the artifacts may change over time. To handle
this, you can either specify a dependency as changing on the
dependency tag, or use the changingPattern and changingMatcher
attributes on your resolvers to indicate which revision or group of
revisions should be considered as changing.
Once Ivy knows that a revision is changing, it will follow this
principle to avoid checking your repository too often: if the module
metadata has not changed, it will considered the whole module
(including artifacts) as not changed. Even if the module descriptor
file has changed, it will check the publication data of the module to
see if this is a new publication of the same revision or not. Then if
the publication date has changed, it will check the artifacts' last
modified timestamps, and download them accordingly.
So if you want to use changing revisions, use the publish task to
publish your modules, it will take care of updating the publication
date, and everything will work fine. And remember to set
checkModified=true" on your resolver too!

Accessing a property of a sibling project dependency

Let's say I have
<properties>
...
<module.deployPath>/admin</module.deployPath>
...
</properties>
in the pom.xml of the project A.
And now I'd like to access ${module.deployPath} in another project B where project A is listed as dependency of project B.
Is this possible somehow without using external property files or settings.xml?
Thank you for your help!
Cheers,
b
Staying strictly within Maven's property access mechanism, I'm almost certain you can't do that. If you were to add the GMaven plugin and write some Groovy code, then it would probably be possible to get and parse the dependency's pom to get at the property you're looking for.

How to find unneccesary dependencies in a maven multi-project?

If you are developing a large evolving multi module maven project it seems inevitable that there are some dependencies given in the poms that are unneccesary, since they are transitively included by other dependencies. For example this happens if you have a module A that originally includes C. Later you refactor and have A depend on a module B which in turn depends on C. If you are not careful enough you'll wind up with both B and C in A's dependency list. But of course you do not need to put C into A's pom, since it is included transitively, anyway. Is there tool to find such unneccesary dependencies?
(These dependencies do not actually hurt, but they might obscure your actual module structure and having less stuff in the pom is usually better. :-)
To some extent you can use dependency:analyze, but it's not too helpful. Also check JBoss Tattletale.
Some time ago I've started a maven-storyteller-plugin to be able to deeper analyze the poms, but the project is very far from production/public use. You can use the storyteller:recount goal to analyze the unused/redundant dependencies.
The problem with the whole story is - how to determine "unused" things. What is quite possible to analyze is for instance class references. But it won't work if you're using reflection - directly or non-directly.
Update November 2014.
I've just moved my old code of the Storyteller plugin to GitHub. I'll refresh it and release to the central so that it's usable for others.
I
personaly use the pom editor of M2Eclipse to visually view the dependency tree (2D tree). Then I give a look in my deliverable (war, ear) lib directories. Then still in M2Eclipse pom dependencies viewer I go to every 3rd party, and right click on the dependency I want to exclude (an exclusion is added automatically in the right dependency).
There is no golden rules, simply some basic tips:
a lot of pom are not correct: a lot of 3rd party libs out there require way too much dependencies in the default compile scope, if everybody carefully craft their pom, you must not have so much unwanted dependencies.
you need to guess by the name of dependencies what you will have to exclude, best example are parsers, transformer, documentbuilder: xalan, xerces, xalan alfred and co. try to remove them and use the internal jdk1.6 parser, common apache stuff, log4j is also worth looking at.
look also regularly in lib delivery if you do not have duplicate libraries with different version (the dependency resolver of maven should avoid that)
go bottom up, start with your common modules, then go up till the service layer, trimming down dependencies in every module, dont try to start in modules ear/war, it will be too difficult
check often if your deliverable are still working, by either testing or comparing and old deliverable with the new one (especially in web-inf/lib directory what has disappeared with winmerge/beyoncompare)
When you have A -> B, B -> C, and then refactor such that A -> (B, C). IF it is the case that A still compiles against B, you very much don't want to simply pick up the dependency because you receive it transitively.
Think of the case when A -> (B-1.0, C-1.0), B-1.0 -> C-1.0. Everything's in sync, so to avoid "duplication" you remove C from A's dependency. Then you upgrade A to use B-2.0 -> C-2.0. You begin to see errors because A wants C-1.0 classes but found C-2.0 classes. While quickly reconcilable in this scenario, it is far less so when you have lots of dependencies.
You very much want the information in A's pom that says that it explicitly expects to find C-1.0 on the classpath so that you can understand when you have transitive dependency conflicts. Again, Maven will do the job of ensuring that the "closest" version of any particular jar ends up on your classpath. But when things go wrong - you want all the dependency metatdata you can get.
On a slightly more practical note, a dependency is unused when you can remove it from your pom and all of your unit/integration/acceptance tests still pass. ;-)

Cruise Control - Parent / Child projects

I am using cruise control to constantly check my projects and so far it appears to be working better than continuum except for some minor issues.
If I have a project that depends on several other projects and I update one of those dependencies without updating its version number thus requiring no change in the parent pom, the parent will never get rebuilt.
Is this possible, or should I just go back and keep incrementing the pom after each change then make the corresponding changes in the parents as needed?
I was hoping this would be done automatically (if cruise control had tighter maven integration), so that I would magically know this change broke something downstream.
I am guessing my new format will probably be:
${date}.${buildNumber}
2009.12.18.1
Thanks,
Walter
If your projects are in a parent->child relationship in maven, building the parent should also the build its modules with the newly resolved dependencies everytime if you are using the install goal.
Based on your description, it sounds like you don't have a parent project with modules but instead of a handful of separate projects with dependencies between them. In this case, I would suggest you do two things
Change the versions in top level of your poms and in your to include -SNAPSHOT on the end. This forces maven to check for new versions of any dependency in a specified timeframe - daily by default. This behavior can by altered by specifically changing the updatePolicy for your repositories - you can have it check every single time if you wish. When it comes to tag and then build/release your projects, you'll want to remove the -SNAPSHOT qualifier for the release, and then re-add it back in after incrementing your version number to support your next development cycle.
In your CI server, you can force projects to build in succession. Since it looks like you switched to Hudson, it should involve setting up build trigger based on the completion of another project just like you'd like add a trigger for scm polling.
Unfortunately I don't know enough about cruise control to directly answer your question.
However I have had positive experience with Hudson. Hudson is widely used as a CI server, is free, and has excellent Maven integration plus handles what you describe perfectly.