I’ve been using Maven 1 for close on to five years now. I’ve been meaning to upgrade to Maven 2 for pretty much all of that time but never quite got round to it. A combination of my starting work on a new project and finding some nasty bugs in Maven 1 has finally nudged me towards Maven 2.
Surprisingly, in my team of around a dozen developers, we’ve had only minimal exposure to Maven 2. Everyone has stuck loyally to the now completely obsolete and unsupported Maven 1. I think everyone hopes someone else will do the hard work first.
As we have dozens of build projects in our repo I can’t migrate them all at once. I’m just doing my project and its immediate dependencies. Unfortunately, this causes problems for the old Maven 1 projects as Maven 2 repos are not compatible with Maven 1. So during the transition period I must ensure that both old style Maven 1 projects and new style Maven 2 projects have access to their dependencies from one or other of the repos.
As you’d expect, the easy bit is getting Maven 2 to access legacy Maven 1 repos. You can simply define a repo as ‘legacy’ when configuring it in the pom:
<project> ... <repositories> <repository> <snapshots> <enabled>true</enabled> </snapshots> <id>my-m1-repository</id> <name>Maven 1.x Repository</name> <url>http://repostory.mycompany.com/maven1</url> <layout>legacy</layout> </repository> </repositories> ... </project>
A harder job is getting your old Maven 1 projects to see your newly built Maven 2 artifacts. As far as I’m aware, there’s just no way to get Maven 1 to recognise a Maven 2 repo. So the only solution involves putting artifacts built using Maven 2 into a legacy Maven 1 repo. I can see a few ways of doing this:
1. Continue to use the legacy repo
This is simplest to do. You maintain both Maven 1 and Maven 2 repos on your dev machine but your remote (deploy) repo is marked as ‘legacy’:
<project> ... <distributionManagement> <repository> <uniqueVersion>false</uniqueVersion> <id>corp-maven1</id> <name>Corporate Repository</name> <url>file:///repo1/maven1</url> <layout>legacy</layout> </repository> ... </distributionManagement> ... </project>
So when you run the deploy phase (mvn deploy), you copy your artifact to your old maven 1 repo. This could be your corporate repo on a shared server or it could even be your local Maven 1 repo.
This solution is simple but unfortunately it ties you to a Maven 1 style repo forevermore.
2. Periodically copy the contents of Maven 2 to Maven 1
A simple batch script run periodically ensures that any new artifacts deployed to your Maven 2 repo get copied over to the old Maven 1 repo. That way all required artifacts are always available in the Maven 1 repo if legacy projects need them. However, this is using behaviour outside of the standard Maven installation (your own custom batch script) and you may run into trouble if you run a Maven 1 project before the repos have synced.
3. Use Nexus repository manager
Nexus is a repository manager from Sonatype. Nexus can proxy your Maven 2 repo for Maven 1 clients. It also does all sorts of other nice things like removing old snapshots so dev builds don’t clog your repo and provides RSS feeds of new artifacts. It’s also got a nice web UI that lets you search for artifacts from the browser (how often have you forgotten the exact version number that you’re looking for?) and deploy new artifacts to the repo without mucking about with fiddly mvn command line syntax. Even if you don’t need to serve your repo for old Maven 1.x clients, this is worth using for all but the most trivial of corporate repos.
4. Use the Maven One plugin
Maven 2 comes bundled with a plugin called (slightly confusingly) maven-one. This contains a handy goal called ‘one:convert’ that will convert your old Maven 1 project.xml to a new pom.xml. Or so it claims. In practice this plugin is a bit simplistic and will choke on anything but the simplest project.xml. We found it easier to knock up some XSLT to do this job for us.
The goals we’re more interested in though, are ‘one:maven-one-install-repository‘ and ‘one:maven-one-deploy-repository‘. Executing these goals will install / deploy your artifact to a Maven 1 repository. Thes goals will bind to your install / deploy phases to install / deploy to your old Maven 1 repo as well as the usual Maven 2 repo. Like this:
<plugins> <plugin> <artifactId>maven-one-plugin</artifactId> <version>1.0</version> <executions> <execution> <goals> <goal>install-maven-one-repository</goal> <goal>deploy-maven-one-repository</goal> </goals> <configuration> <remoteRepositoryId>corp-maven1</remoteRepositoryId> <remoteRepositoryUrl>file:///repo1/maven1</remoteRepositoryUrl> </configuration> </execution> </executions> </plugin> </plugins>
One last thing…
Maven: The Complete Reference is a decent reference book for Maven 2. It’s perhaps not as complete as the title might suggest but it is available for free as browsable HTML or as a PDF download. Free registration is required for the PDF.