Monday, September 3, 2007

Bootstrap When Using Pom Inheritance

The problem:

Parent pom files can allow you to standardize many projects. Project maintenance tasks such as updating shared attributes like repository locations is easy. You can also define things like how tests are run, reports to generate and more.

When using a parent pom it must be accessible from one of your defined Maven repositories, but... often times the parent pom contains your repository definitions. When you clean your local repository (removing the parent pom locally) you will no longer have defined repository locations. You will therefore not be able to download the parent pom (if installed in a network accessible repository), and not be able to build projects that inherit from this pom.

The solution:

It is common to have a company/organization repository that will contain any parent poms used in inheritance of projects. When you need to get one of these parent poms you will need access to this repository. That means you will need to define the repository. There are a number of ways to do this: put a definition in your projects pom (cold), put a definition in your settings.xml (getting warmer). Neither of these are that great.

Putting the repository information into the project makes for crappy upkeep. Think, if you have 10 projects with poms that contain repository definitions, and the repositories move, you need to update all those files with the new information. Therefore do not put (unless you are using Maven small scale...).

Don't just put the repository definition into the settings.xml file either. If you do this every time you run Maven this repository will be searched for artifacts. It is much cleaner to define the repository in a profile, in your settings.xml file.

Why use a profile? Profiles allow you to enable certain features when needed. In our case we want to activate the parent pom repository definition. So first you need some xml in your pom like so:

<profiles>
<profile>
<id>bootstrap</id>
<repositories>
<repository>
<id>parent</id>
<name>Maven repository -- bootstrap</name>
<url>http://abc.com/mvn2</url>
</repository>
</repositories>
</profile>
</profiles>

This piece of gold will let Maven search the given repository when needed. To activate this you would put the string "-Pbootstrap" in with the Maven command you are executing. How about an example?
mvn -Pbootstrap clean package
Once you have run this command once the parent pom should be downloaded locally, so you will not need to run activate the bootstrap profile very often.