Inside Spring Boot Executable JAR: How JarLauncher and Custom Class Loading Work
This article explains how Spring Boot's spring-boot-maven-plugin creates an executable JAR, details its internal structure, the role of JarLauncher and the Spring Boot Loader, and shows how the custom LaunchedURLClassLoader loads classes from embedded dependencies.
Spring Boot provides the spring-boot-maven-plugin to package an application as an executable JAR. Adding the plugin to the pom generates a JAR with a specific internal structure (META-INF, lib, loader classes, and application classes).
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>The generated JAR can be run directly with java -jar executable-jar-1.0-SNAPSHOT.jar. Inside the JAR there are four types of entries: META-INF folder with MANIFEST.MF, lib directory with third‑party JARs, Spring Boot loader classes, and the application’s own classes.
The MANIFEST.MF defines Main-Class: org.springframework.boot.loader.JarLauncher. When the JAR is executed, JarLauncher’s main method creates a custom class loader, locates the Start-Class from the manifest, and launches the Spring application.
Spring Boot Loader abstraction
Launcher is the abstract base class for JarLauncher, WarLauncher and PropertiesLauncher. Archive abstracts the underlying archive (e.g., JarFileArchive for JAR files, ExplodedArchive for directories). JarFile wraps a JAR and provides entries.
JarLauncher execution flow
JarLauncher’s main constructs a JarLauncher and calls launch(args). The launch method registers the custom URL protocol handler, builds a class loader from the archives in lib, obtains the main class from the manifest, and invokes it via a MainMethodRunner in a new thread.
Custom class loader LaunchedURLClassLoader
LaunchedURLClassLoader overrides loadClass to first try a root class loader, then find classes locally in the JAR URLs, and finally delegate to the parent. Its findClass method resolves the class name to a path, locates the resource via the URLClassPath, and defines the class.
// Register the URL protocol handler
JarFile.registerUrlProtocolHandler();
// Create LaunchedURLClassLoader with URLs to embedded JARs
LaunchedURLClassLoader classLoader = new LaunchedURLClassLoader(
new URL[]{
new URL("jar:file:/path/to/executable-jar-1.0-SNAPSHOT.jar!/lib/spring-boot-loader-1.3.5.RELEASE.jar!/"),
new URL("jar:file:/path/to/executable-jar-1.0-SNAPSHOT.jar!/lib/spring-boot-1.3.5.RELEASE.jar!/")
},
LaunchedURLClassLoaderTest.class.getClassLoader()
);
// Load classes
classLoader.loadClass("org.springframework.boot.loader.JarLauncher");
classLoader.loadClass("org.springframework.boot.SpringApplication");
classLoader.loadClass("org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration");Purpose of Spring Boot Loader
Spring Boot defines its own rules for executable JARs: third‑party dependencies are placed under /lib, URLs use the custom !/ separator handled by org.springframework.boot.loader.jar.Handler, and the main class is JarLauncher (or WarLauncher for WARs). These features are enabled by the spring-boot-maven-plugin.
Signed-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 Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack 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.
