Let's suppose you are doing development against the Project Darkstar server. As part of your mini development cycle, in addition to running the unit tests against the server, you also want to run an example application specifically designed to provide performance benchmarks for the system. By convention, this application would specify as a dependency the latest 'SNAPSHOT' of the Project Darkstar server (in this case the latest snapshot is 0.9.7-SNAPSHOT). In order for the example application to be run against your SNAPSHOT, though, you need to build the server component which includes the changes made in your development branch, and install it into your local repository. This is straightforward to do and requires basically an
mvn install
from your development branch. Running the example application will then pick up your latest SNAPSHOT from the local repository, and all is well.However, what if you wish to compare the results of running this example application against both your development SNAPSHOT, and also the latest SNAPSHOT from the trunk. If you execute
mvn install
from these respective codebases, they'll clobber eachother because they both have the same version number (0.9.7-SNAPSHOT). The problem is exacerbated even more if you have multiple development branches that you are working on simultaneously. You can workaround it by rebuilding each copy before running the example, but this is tedious and error prone. You could also make temporary changes to the version numbers of the artifacts by hacking your POMs so that each development branch has a unique version. This is also tedious and error prone, though, and is ugly because it requires reverting changes to your POMs before merging patches into the trunk.Ultimately, we want a solution that meets the following requirements:
- Modifying the POMs or assigning temporary version numbers is not necessary.
- It does not require rebuilding each development version as they are needed.
- Ideally, a simple configuration parameter on the command line is all that is required to specify which development version we wish to use.
~/.m2/repository
directory. However, this location is configurable, and a different location can be swapped in and out depending on your needs.To put this into the context of our example, let's say you have a checked out version of the Project Darkstar server trunk, and you also have two development branches that you are working on, branchA, and branchB. You would then do the following to install each of the respective artifacts into separate local repositories:
trunk $ mvn install -Dmaven.repo.local=/home/owen/.m2/repository-trunk
branchA $ mvn install -Dmaven.repo.local=/home/owen/.m2/repository-A
branchB $ mvn install -Dmaven.repo.local=/home/owen/.m2/repository-B
At this point, you have local repositories which are completely isolated from eachother. You can use each one of them independently to build and/or run your example application against the respective development version of the Project Darkstar server:
example $ mvn package -Dmaven.repo.local=/home/owen/.m2/repository-trunk
example $ mvn package -Dmaven.repo.local=/home/owen/.m2/repository-A
example $ mvn package -Dmaven.repo.local=/home/owen/.m2/repository-B
That's it. No POM hacking, no building and rebuilding the same code, just isolate your development versions with separate local repositories. Hope this helps someone out there.