Why Can Spring Boot Fat JARs Run Directly? Uncover the Secrets
This article explains how Spring Boot packages applications as executable Fat JARs, embeds a web server, uses a special launcher, and defines a main class so the JAR can be run with a simple java -jar command, eliminating the need for separate deployment servers.
1. Fat jar
Unlike a regular JAR, a Spring Boot JAR is a Fat JAR that contains all project dependencies under
BOOT-INF/liband the compiled classes under
BOOT-INF/classes. This means the JAR includes both the application code and every required library, so no external installation of dependencies is needed.
Typical Maven configuration for creating a Fat JAR uses the Spring Boot Maven plugin:
<code><project>
<!-- ... other configurations ... -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
</code>Running
mvn packagecreates a JAR that bundles all dependencies.
2. Embedded server
Spring Boot applications embed a web server such as Tomcat. The required server dependency is added in
pom.xmlor
build.gradle:
<code><dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- ... other dependencies ... -->
</dependencies>
</code>When the application starts, Spring Boot automatically configures and launches this embedded Tomcat.
3. Spring Boot starter
Every Spring Boot app has a main class with a
mainmethod annotated with
@SpringBootApplication, which combines
@Configuration,
@EnableAutoConfiguration, and
@ComponentScan:
<code>import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
</code>Calling
SpringApplication.run()starts the Spring context and the embedded server.
4. Executable JAR
The JAR’s
META-INF/MANIFEST.MFspecifies the main class (
Main-Class). When you execute
java -jar your-app.jar, the JVM reads this entry and invokes the
mainmethod.
In Spring Boot, the main class is
org.springframework.boot.loader.JarLauncher, which loads the Fat JAR, creates a custom class loader, and launches the application:
<code>protected void launch(String[] args) throws Exception {
JarFile.registerUrlProtocolHandler();
// custom class loader loads JAR files
ClassLoader classLoader = createClassLoader(getClassPathArchives());
launch(args, getMainClass(), classLoader);
}
protected String getMainClass() throws Exception {
Manifest manifest = this.archive.getManifest();
String mainClass = null;
if (manifest != null) {
mainClass = manifest.getMainAttributes().getValue("Start-Class");
}
if (mainClass == null) {
throw new IllegalStateException("No 'Start-Class' manifest entry specified in " + this);
}
return mainClass;
}
</code>Thus, a Spring Boot Fat JAR is self‑contained, embeds its server, and defines a launcher, allowing it to be run directly without external containers.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.