Saturday, March 10, 2007

Storing jars in a Maven project

One of the sweetest things about Maven is that depedencies are stored external to your sources: if you depend on Apache Commons Lang 2.3, for example, then you can stick this in the dependencies section of your pom.xml and stop worrying:

<depedency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.3</version>
</dependency>

But what do you do when your dependency is not available in a public Maven repository? For example, the library is too new to be widely available, or is proprietary like the Oracle JDBC driver?

One tack is to establish an internal repository and refer to that in your pom.xml. But sometimes that is not practical, perhaps because of corporate network use restrictions, or for very small projects.

Before Maven, common practice was to stash dependencies into a directory named lib/ or similar underneath the root of your project sources. When no other solution presents itself, you can follow that practice but keep using Maven.

In your pom.xml, add this top-level section:

<repositories>
    <repository>
        <id>project</id>
        <name>Project Maven Repository</name>
        <layout>default</layout>
        <url>file:///./lib</url>
    </repository>
</repositories>

This establishes the lib/ directory underneath your project as a Maven repository relative to your project root. Now you can stash dependencies there, store them with the rest of your project resources, but keep using Maven.

A little bit more

Often I have to re-lookup the documentation on deploy:deploy-file so that I can put a dependency in an internal repository or in the project repository as described above. Here is a magic incantation example:

$ cd /PATH-TO-guice-1.0-DOWNLOAD
# Checkout the SVN 1.0 tag sources to src/
# Note -- need to use the -Dversion=1.0 switch
# because pom says 1.0-RC2 in spite of tag.  Then:
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project -Dfile=guice-1.0.jar \
    -DpomFile=src/pom.xml -Dversion=1.0
# Pack up the javadocs and sources into jars, then:
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project \
    -Dfile=guice-1.0-javadocs.jar \
    -DpomFile=src/pom.xml -Dversion=1.0 \
    -Dclassifier=javadocs
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project \
    -Dfile=guice-1.0-sources.jar \
    -DpomFile=src/pom.xml -Dversion=1.0 \
    -Dclassifier=sources

I now have the splediferous Guice 1.0 dependency in my project repository, and can use it in my pom.xml with:

<depedency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>1.0</version>
</dependency>

1 comment:

Anonymous said...

My maven would not accept a relative path to ./lib so I found a work around

file://${basedir}/lib/




project
Project Maven Repository
file://${basedir}/lib/