A: 

This is really the same problem as someone needing to branch code they are working on. You need some form of identifier to be able to get at the specific version until you merge back to the mainline development of that component.

The dependency classifier may be something worth looking into. You'll still need to have developers that will properly identify their modified code.

Nick Veys
A: 

we work with a "Super Parent".pom-project, in it the versions are defined as properties and in every child.project, the versions are set with those properties

in addition the real projects have no version set, instead they inherit it from their parent pom-project (incl. groupId etc.)

with this set up the versions are only defined in some parent pom-projects, thus the needed setup is minimized

e.g. this structure

  • super parent pom-project (all 3rd party versions as properties defined, e.g. 2.5.6 spring-framework) ---- persistence-parent pom-project, inherits all from super parent ------ persistence-foobar jar project, inherits all from persistence-parent ---- util-parent

etc.

only versions you see are the ones inside the parent relations example:

        <modelVersion>4.0.0</modelVersion>
<artifactId>foo-bar-foo</artifactId>
<packaging>jar</packaging>
<name>whatever</name>
<description>...</description>
<parent>
    <groupId>org.foo.bar</groupId>
    <artifactId>persistence-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>foo-bar</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>foo-bar</artifactId>
        <version>${project.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>org.springframework.jdbc</artifactId>
        <version>${parent.spring.version}</version>
    </dependency>

it works this way, because inside the pom you can use already defined values like version, even if the version is set via inheritance

we combine this with module setups inside the parent projects to make the builds easier

Michael Lange
+1  A: 

This is something I find very difficult with maven and internal projects; you have two version control systems (maven's, which, quite frankly, isn't very good) and your source code control's (which, assuming it's CVS or better, supports real workflow).

Here's how we do it:

report --depends on--> core
web    --depends on--> core

We use the maven release plug:

report's pom, during development, would have a SNAPSHOT version matching what's in core's pom. I do a mvn clean install in core, then I can see those changes in report in my local environment.

When I do a release of report, I must first release core via the maven release plug. When I I use it on core, it asks me to set the version of core to release (i.e. remove the -SNAPSHOT), to which I say yes, and the resulting released artifact doesn't depend on a SNAPSHOT release. When the release plugin is done, the report pom now depends on the next SNAPSHOT release of core (though you can override this during mvn release:prepare if you want).

The devs on web then get an email that a new version of core is available and they can choose to use it if they wish. Our policy is that they should update before releasing.

davetron5000
Say last releases were report 2.0 --> core 1.5. Checked-in poms: report 2.1-SNAPSHOT-->1.5; core 1.6-SNAPSHOT. Devs want to update both, change report to depend on 1.6-SN. Then, we update core to 1.6, deploy it, update it to 1.7-SN, update report to 2.1-->1.6, deploy *it*, update it to 2.2-SN? Yes?
Zac Thompson
I'm not sure I follow totally, but you might be a bit backward. You would change and release core first, so 1.6 is released and 1.7-SNAP is the new dev version. Then, when you mvn release:prepare report, it will set core's SNAP version to non-SNAP for you
davetron5000
Fine, but if the devs are wanting to confirm their changes to core are going to work with the changes to report, then what? That's why I say that before anything else, they'd need to update the report pom (currently depending on 1.5) to depend on 1.6-SNAPSHOT.
Zac Thompson
Well, if you are saying that core can't be released unless you know it doesn't break its dependees, that gets tricky, and is a bit backward.
davetron5000
Yes, I meant to say that the other way around: if they want to confirm the new 'report' will work with the new 'core'. I don't want them to have to wait for their changes to core to be released before they can work on report.
Zac Thompson
I guess you'd need to loosen the requirements for "releasing a version to the maven repo". You could let anyone create a new point release, and maybe have a more involved review process for major/minor.
davetron5000
+3  A: 

Try to layout your builds such that modules that need to be developed together are released together. This will let the maven release plugin do most of the work for you.

For dependencies that really should have a separate lifecyle...because they change infrequently or are shared by multiple projects, you want to handle those differently. They way I do it is to keep the dependencies at the last release version until a change actually requires an upgrade to the next snapshot. In this way when you go to release the product, you will find all the things that may also be released simply by following the snapshot trails.

I find it also helpful to keep the external dependency versions specified as properties in the top pom of my project. This makes it easy to see at a glance what needs to be released. You can see an example of the Nexus pom here (look down around line 120).

Brian Fox
I want "release the product" to be automated as-needed. Having an unpredictable set of snapshot dependencies would make that difficult, but it will usually be unnecessary (because I'll just be working from a newer "release" instead). The first part ("modules developed together are released together") is what I'm trying to do now.
Zac Thompson
I'm definitely going to have to do some variation of this solution ... it seems I'll need to be using Maven 2.1 or higher in order for the release plugin to work the way I need it to for the first part. I'm not sure how the scm part will shake out, but it has become clear that this is the "true way". Thanks!
Zac Thompson