Explain Codes LogoExplain Codes Logo

Maven: add a dependency to a jar by relative path

java
maven
dependency-management
local-repository
Nikita BarsukovbyNikita Barsukov·Nov 23, 2024
TLDR

Quickly embed a local JAR in your Maven project by setting up a system scope dependency that points directly to your file using systemPath. Just copy, paste and tinker:

<dependency> <groupId>local</groupId> <artifactId>my-jar</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${project.basedir}/replace/this/with/your/jar/location.jar</systemPath> </dependency>

Remember to replace ${project.basedir}/replace/this/with/your/jar/location.jar with your actual JAR's location.

Heads up! This solution isn't ideal for situations where your code will be shared or moved into production as it relies on a specific path.

A deep dive into better local dependency management

Ditch 'system' scope, say hello to file repository

Using the system scope might seem like the quick remedy, but it's the equivalent of putting a band-aid on a broken pipe. Instead, consider defining a file repository directly in your pom.xml:

<repositories> <repository> <id>repo-that-rocks</id> <name>Your Local Repository</name> <url>file://${project.basedir}/local-repo</url> </repository> </repositories>

Next, add your JAR as a dependency:

<dependency> <groupId>local</groupId> <artifactId>my-jar</artifactId> <version>1.0</version> </dependency>

Now, your project will look for the JAR in the local-repo directory. Your code is cleaner, you can pat yourself on the back and your teammates will thank you.

Tame your third-party JARs

If you're dealing with proprietary JARs, bring them under control by installing them in your local Maven repository using the install:install-file plugin:

mvn install:install-file -Dfile=path-to-your-jar.jar -DgroupId=local -DartifactId=my-jar -Dversion=1.0 -Dpackaging=jar

Now, your proprietary JARs are well-behaved and live snugly in your local Maven repository.

For optimal manageability, be sure to use fully qualified plugin names. Think of it as introducing yourself with your full name at a conference to avoid confusion.

How to handle JARs like a boss in a corporate setting

If you're swimming in a corporate environment, consider setting up a central corporate repository. This is like having a private library where you store and manage all artifacts. Nexus and Artifactory are the cool kids in the neighborhood to consider for this.

In case you're hanging out with a smaller team or flying solo, neatly storing your JARs within a 3rdparty directory in source control could be your best companion.

Setting up a local file repository (Get your DIY mode on!)

Declare the local repository in your POM

In your pom.xml, declare a local file repository. It's like stating "Hey Maven, here's a map to my JAR!":

<repository> <id>super-local-repo</id> <url>file://${project.basedir}/local-repo</url> </repository>

Next, add your JAR as a dependency. Watch out, no system scope here!

Large project? Break it down!

For larger projects, think about multi-module setups. You can create a dedicated module, probably a "bom" or "dependencies" project, which serves as your traffic controller of dependencies.

Embrace Maven variables

Maven's variables (${basedir}) are your white knights. They keep the path dynamic and environment-independent, thus freeing you from hardcoding paths and making your project more portable.

Avoid potholes: Potential pitfalls and their solutions

Avoid systemPath

While the allure of systemPath is hard to resist, the tradeoff is the maintainability of your project.

Version-controlled JARs

Version control is not just for your code. It's a great place for your third-party JARs too. Just keep the 3rdparty directory well-structured and clean.

Automate JAR installation

Automate the installation of your proprietary JARs during the build process. Configure the maven-install-plugin in your pom.xml:

<plugins> <plugin> <artifactId>maven-install-plugin</artifactId> <executions> <execution> <phase>initialize</phase> <!-- because it's always good to be initialize --> <goals> <goal>install-file</goal> </goals> <configuration> <file>${basedir}/replace/this/with/your/jar/location.jar</file> <groupId>local</groupId> <artifactId>my-jar</artifactId> <!-- who's my-jar, you ask? that's our local JAR --> <version>1.0</version> <packaging>jar</packaging> </configuration> </execution> </executions> </plugin> </plugins>