Fading Coder

An Old Coder’s Final Dance

Home > Tech > Content

Adding Local JAR Dependencies in Maven and Packaging Strategies

Tech 1

When a project depends on JARs that are not available in a remote repository, you can bring them into a Maven build in two primary ways. The first publishes the artifact into your local repository and treats it like a normal dependency. The second wires the JAR directly via a system-scoped dependency and adjusts packaging to include it.

Option 1: Install the JAR into the Local Maven Repository

Use this when the third-party JAR is produced by a Maven build (or you can suppply metadata) and you want Mavan to manage it like any other dependency.

  1. Install the JAR into your local repo:
a: Install with explicit coordinates (and generate a POM if needed)
mvn install:install-file \
  -Dfile=./libs/my-lib-1.2.3.jar \
  -DgroupId=com.example.libs \
  -DartifactId=my-lib \
  -Dversion=1.2.3 \
  -Dpackaging=jar \
  -DgeneratePom=true
  1. Declare the dependency in your pom.xml:
<dependencies>
  <dependency>
    <groupId>com.example.libs</groupId>
    <artifactId>my-lib</artifactId>
    <version>1.2.3</version>
  </dependency>
</dependencies>

Maven will now resolve the atrifact from your local repository, and it will be handled like any other transitive dependency.

Option 2: Use a system-scoped dependency and point to a local file

Use this when the JAR cannot be (or should not be) published to a repository and you need to reference it directly from disk. You must then ensure it is packaged with your application and available on the runtime classpath.

  1. Add a system-scoped dependency that references the local file path:
<dependencies>
  <dependency>
    <groupId>com.vendor</groupId>
    <artifactId>vendor-lib</artifactId>
    <version>0.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/vendor/vendor-lib.jar</systemPath>
  </dependency>
</dependencies>
  1. If you build a Spring Boot application, instruct the Spring Boot Maven Plugin to include system-scoped depandencies when creating the executable archive:
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <includeSystemScope>true</includeSystemScope>
      </configuration>
    </plugin>
  </plugins>
</build>
  1. If you pacckage with the Maven JAR Plugin (non-Boot or plain JAR), add the system JAR to the manifest class path so it’s discoverable at runtime:
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>com.example.app.Main</mainClass>
          </manifest>
          <manifestEntries>
            <Class-Path>./lib/vendor-lib.jar</Class-Path>
          </manifestEntries>
        </archive>
        <outputDirectory>${project.build.directory}/dist</outputDirectory>
      </configuration>
    </plugin>
  </plugins>
</build>
  1. Example build section that separates the application JAR, libraries, and resources into a distribution layout:
<build>
  <finalName>my-app</finalName>

  <sourceDirectory>src/main/java</sourceDirectory>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <targetPath>${project.build.directory}/dist</targetPath>
      <excludes>
        <exclude>**/*.java</exclude>
      </excludes>
    </resource>
  </resources>

  <testSourceDirectory>src/test/java</testSourceDirectory>
  <testResources>
    <testResource>
      <directory>src/test/resources</directory>
      <filtering>true</filtering>
      <excludes>
        <exclude>**/*.java</exclude>
      </excludes>
    </testResource>
  </testResources>

  <plugins>
    <!-- Include system-scope JARs when building a Spring Boot executable -->
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <includeSystemScope>true</includeSystemScope>
      </configuration>
    </plugin>

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <skipTests>true</skipTests>
      </configuration>
    </plugin>

    <!-- Copy all resolved dependencies (excluding systemPath unless included by plugin logic) -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <phase>package</phase>
          <goals>
            <goal>copy-dependencies</goal>
          </goals>
          <configuration>
            <outputDirectory>${project.build.directory}/dist/lib</outputDirectory>
          </configuration>
        </execution>
      </executions>
    </plugin>

    <!-- Create the application JAR with a manifest that points to libs/ -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>com.example.app.Main</mainClass>
          </manifest>
          <manifestEntries>
            <!-- Explicitly include any system-scoped JARs that won’t be copied automatically -->
            <Class-Path>./lib/vendor-lib.jar</Class-Path>
          </manifestEntries>
        </archive>
        <outputDirectory>${project.build.directory}/dist</outputDirectory>
      </configuration>
    </plugin>
  </plugins>
</build>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.