Browse files

Maven: Add Local JAR Dependency to Classpath

  • Loading branch information...
markkolich committed Sep 27, 2015
1 parent 9f4b839 commit ed8f6b7f55088c791fa46a57461eb84fafc6faa5
Showing with 112 additions and 0 deletions.
  1. +112 −0 content/entries/
@@ -0,0 +1,112 @@
I've been getting back into [Maven]( lately, converting the build system behind several of my [personal projects on GitHub]( into something a little more sane and well-travelled. For reasons yet-to-be formally discussed, I've embarked on a mass migration away from [SBT]( — albeit, I still have a number of published projects [backed]( [by]( [SBT](
### SBT Rant
Although I'm still using it sparingly, SBT has left a bitter taste in my mouth. The long-and-short of it is that I'm tired of everything in SBT being a complicated puzzle backed by poor documentation — I just want to get stuff done. I wish I had the *countless* hours of my life back that I spent figuring out how to accomplish very specific (yet seemingly common) tasks with SBT. Build definitions *do not* need to be written in [Turing-complete languages](, and in my humble opinion, SBT is a perfect example of [what not to do](
### Maven
I was refactoring a personal project to use Maven the other day, and stumbled across a need to "add a local JAR to my classpath". That is, I have a `.jar` file on disk [from many moons ago](, that is not in any public Maven repository yet I need to add it to the `compile` scope of my project.
#### Bad: The `system` Scope
A quick search of the Interwebz clearly calls out a worst practice: using the Maven `system` scope.
The `system` scope was designed to deal with "system" related files &mdash; files sitting in some fixed location, like Java's core `rt.jar`. To discourage bad behavior, the Maven contributors intentionally refused to make pathname expansion work correctly in the context of the `<systemPath>` tag in the `system` scope. In other words, `${basedir}/lib/foo.jar` below will not resolve:
Don't do this.
#### Good: Use a Local Repository
The [best practice]( is to "publish" the `.jar` file to a local Maven repository nested within the project. Yes, you read that correctly, publish the `.jar` to a `~/.m2` like repo within your project that is checked into SCM!
Here's how...
On disk, your project probably looks something like this:
1) Create a `lib` directory in your project root &mdash; this `lib` directory will act as a local Maven repository within the project.
cd project
mkdir lib
2) Download the `.jar` file to disk, and use `mvn` to publish the `.jar` to the `lib` directory.
In this example, I'm publishing the [Gagawa]( library I wrote and open-sourced many years ago.
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file \
-Dfile=~/Desktop/gagawa-1.0.1.jar \
-DgroupId=com.hp \
-DartifactId=gagawa \
-Dversion=1.0.1 \
-Dpackaging=jar \
If all went well, you can find your artifact published inside of `lib`.
project$ find lib
Note the structure here mimics what you'd find in `~/.m2`.
3) Now, in your `pom.xml`, declare the `lib` directory in your project a Maven repository.
4) And lastly, in your `pom.xml` declare a dependency on the local `.jar` like you would for any other classpath dependency.
At runtime, Maven will consult the local repo at `${basedir}/lib` in addition to `~/.m2` and any other remote repositories you have defined.
Ship it!

0 comments on commit ed8f6b7

Please sign in to comment.