How to Load External JARs into Spring Boot: Simple 2‑Step Solutions

This guide explains two straightforward steps to load external JAR files into the JVM and make Spring Boot scan them, covering three implementation options—extending the classpath, using Spring Boot’s loader.path parameter, and creating a custom classloader—along with configuration details, Maven settings, and runtime considerations.

Java Captain
Java Captain
Java Captain
How to Load External JARs into Spring Boot: Simple 2‑Step Solutions

Implementation Plan

Implementing this is simple and only requires two steps:

Load the class into the JVM.

Make Spring scan the class.

Java frameworks and complex source code can be hard to understand, especially the Spring family, so clarifying the overall implementation steps first is helpful.

Loading Classes into the JVM

Assume the JAR to be loaded resides in /user/local/java/plugins. There are three ways to achieve step 1:

Expand the -cp option of the AppClassLoader to load external JARs.

Use Spring Boot’s startup parameter loader.path.

Implement a custom classloader to load JARs from a specified location.

Options 1 and 3 are provided by the JDK; option 2 is an extension from Spring Boot.

Option 1: Expand -cp via AppClassLoader

You can specify the classpath with classpath, but its effect depends on the JAR’s launch mode (Main‑function launch vs. JAR execution).

Image
Image

After Spring Boot packaging, the MANIFEST.MF looks like:

Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 18
Implementation-Title: intelligent-soul
Implementation-Version: 0.0.1-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.test.MyApplication
Spring-Boot-Version: 2.6.15
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

Therefore the application must be started via the

Main-Class
JarLauncher

instead of the traditional JAR launch command. The command becomes:

java -cp /user/local/java/plugins org.springframework.boot.loader.JarLauncher

Advantage: simple implementation.

Disadvantage: every JAR uses the same start command, making differentiation difficult.

Option 2: Use Spring Boot’s loader.path Parameter

Spring Boot applications are usually packaged as JARs and started with java -jar boot.jar, where -cp is ineffective. By adding loader.path, you can specify additional class‑loading paths, but it only works under certain conditions.

Image
Image

The default Main-Class for Spring Boot packaging is JarLauncher. To make loader.path effective, configure the Main-Class as PropertiesLauncher in Maven:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <includeSystemScope>false</includeSystemScope>
        <!-- Enable loader.path by using ZIP layout -->
        <layout>ZIP</layout>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
  <finalName>Test</finalName>
</build>

The layout can be set to:

JAR : standard executable JAR ( Main-Class: org.springframework.boot.loader.JarLauncher).

WAR : executable WAR with servlet container dependencies under WEB-INF/lib-provided ( Main-Class: org.springframework.boot.loader.WarLauncher).

ZIP : directory‑style JAR (

Main-Class: org.springframework.boot.loader.PropertiesLauncher

).

MODULE : packages all dependencies except those with provided scope, without bundling any Spring Boot launcher.

NONE : packages all dependencies but excludes any Spring Boot launcher.

Note that PropertiesLauncher starts noticeably slower (≈20 s) than JarLauncher (≈8 s) for the same program.

Option 3: Custom Classloader

This approach invokes a custom classloader at a specific program point to load JARs from a fixed directory or an environment‑defined path. It offers high customisation but timing control can be tricky.

// Custom classloader invocation example
SpringApplication.run(SpringBootDemoApplication.class, args);

Option 4: Modify System Classloader

Using -Xbootclasspath/a or altering java.ext.dirs changes the system classloader’s behaviour, which is unsafe and not recommended.

Scanning Loaded Classes into the Spring Container

For business JAR classes, pre‑define the scan base packages in Spring Boot, e.g., com.demo. Then the plugin JAR placed under that package will be detected automatically.

@SpringBootApplication(scanBasePackages = {"com.demo"})
public class SpringBootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}

If the package prefix does not match, add the required auto‑configuration classes to the plugin JAR’s META-INF/spring.factories file, for example for MyBatis‑Plus:

# Auto Configure
org.springframework.boot.env.EnvironmentPostProcessor=\
  com.baomidou.mybatisplus.autoconfigure.SafetyEncryptProcessor
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.baomidou.mybatisplus.autoconfigure.IdentifierGeneratorAutoConfiguration,\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavamavenSpring Bootclassloaderjar-loading
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.