When Mavenizing an existing project, a common problem is determining the correct Maven dependency to specify in your POM file for a jar in your old project’s classpath so that you will end up with the exact same jar.
There are two things you need to determine:
- What’s the version of the jar?
- What’s the dependency declaration corresponding to a given version of a jar?
In attempting to resolve these issues you may run into additional problems:
- What to do if I can’t determine the version of a jar?
- What to do if the jar I want is not available in the Maven central (or your private corporate) repositories?
Here we provide some guidance on resolving these issues.
What’s the version of the jar?
Lets say that the project you are trying to Mavenize has a jar file in its classpath called commons-collections.jar. Now you need to determine which version of commons-collections this is.
This raises an important point:
The only fool-proof way to determine that a given jar file corresponds to a specific Mavenized artifact is to ensure that they have the same MD5 or SHA1 signature.
So, the first step is to obtain a signature. In Linux/Unix or Cygwin on Windows you can:
- Determine the MD5Sum signature via:
$ md5sum commons-collections.jar d1dcb0fbee884bb855bb327b8190af36 *commons-collections.jar
$ openssl dgst -md5 commons-collections.jar MD5(commons-collections.jar)= d1dcb0fbee884bb855bb327b8190af36
- Determine the SHA1 signature via:
$ openssl dgst -sha commons-collections.jar SHA(commons-collections.jar)= d4068a739e7c737b8de9b30a659d3b8dac48ea86
The next step is to determine what version this matches. The first thing to try is to Google that MD5Sum, as this will often provide a quick answer.
If that doesn’t work then you should check the Manifest.mf file in your jar’s meta-inf directory for lines like:
... Specification-Version: 3.1 Specification-Vendor: Apache Software Foundation Specification-Title: Commons Collections Implementation-Version: 3.1 ...
Finally, if there are no clues in the Manifest file, you’ll have to use the dates of the files in the jar as a hint to the version to compare against.
What’s the dependency declaration corresponding to a given version of a jar?
Once you think you know what version of the jar you need, you will need to look for it in the repositories.
To find out what is available in the Maven central Repository (for ftp://ibiblio.org/pub/packages/maven2) use the search engine: http://mvnrepository.com/
For our example, we can browse to ftp://ibiblio.org/pub/packages/maven2/commons-collections/commons-collections/3.1/
There we will find the files:
commons-collections-3.1.jar commons-collections-3.1.jar.md5 commons-collections-3.1.jar.sha1 commons-collections-3.1.pom
So, now we can inspect the signatures to confirm the version. If, for some reason, there were no signatures files, we could download the jar and calculate the signatures (as above) to confirm the version.
Finally, the POM file will contain the Maven vector (groupId, artifactId, and version) to identify the artifact. So, in this case the dependency element we would need to add to our project’s POM file is:
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.1</version> </dependency>
If all else fails….
In some cases you may find that you either cannot determine the version of a jar, or find that it is not available in any repository. The may be because:
- it was never published to a repository
- it is an old snapshot version that is no longer available
- the jar has been modified by someone
Whatever the reason, you have two choices:
1. Switch to a version that is available
This means that your new build will be different, so you will need to test the results carefully. However, this is often the preferred solution, as you will now be using a known published version. This is especially desirable if you find that the application was previously using a snapshot or pre-release version.
2. Publish the artifact to your private repository
If you cannot find an acceptable substitute, or if the substitute results in problems (e.g. API changes) that you cannot currently modify your application to handle, then the only remaining choice is to publish the artifact to your private repository.
To do this you will need to use the maven deploy:deploy-filegoal.
First you will need to create a POM file for your artifact. This POM file must specify the artifact’s groupId, artifactId, and version as well as the distributionManagement element and the wagon to use for publishing (see your corporate root POM or the POM file of a previously published artifact for an example).
You should also add a <description> and <name> element to the POM to help identify where this artifact came from and why it is being published to your private repository.
Once you have your POM file ready, you can issue the command:
mvn deploy:deploy-file -Dfile=<the file to deploy> -Durl=<url to your repository> -Dpackaging=jar -DrepositoryId=<the repositoryID> -DpomFile=<path to your pom.xml file>