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.
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).
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.idxTherefore the application must be started via the
Main-Class JarLauncherinstead of the traditional JAR launch command. The command becomes:
java -cp /user/local/java/plugins org.springframework.boot.loader.JarLauncherAdvantage: 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.
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.MybatisPlusAutoConfigurationSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
