Skip to main content

Command Palette

Search for a command to run...

Exploring the Magic of Spring Boot runnable standalone jar

Published
Exploring the Magic of Spring Boot runnable standalone jar

Spring Boot uses Spring Boot Gradle Plugin or Spring Boot Maven Plugin to package application as a runnable standalone jar file.

Spring Boot uses the Spring Boot Loader to lauch the Spring Boot jar file usingjava -jar.

Let's uncompress the jar file and see its structure(jar is actually a zip file):

image.png

We see three sub-folders in the uncompressed folder:BOOT-INF,META-INF,org

example.jar
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-BOOT-INF
    +-classes
    |  +-mycompany
    |     +-project
    |        +-YourClasses.class
    +-lib
       +-dependency1.jar
       +-dependency2.jar

BOOT-INF

  1. BOOT-INF/classes: application classes
  2. BOOT-INF/lib: nested dependency jars
  3. BOOT-INF/classpath.idx: the ordering that jars should be added to the classpath
  4. BOOT-INF/layers.idx: allows a jar to be split into logical layers for Docker/OCI image creation

image.png

META-INF

META-INF/MANIFEST.MF: contains information about the files contained in the JAR file

image.png

org

spring boot loader classes

image.png

Explore the Magic

We will explore the steps of running a standalone jar file:

  1. java -jar
  2. Looking for the executable jar’s main entry point in the META-INF/MANIFEST.MF
    Manifest-Version: 1.0
    Main-Class: org.springframework.boot.loader.JarLauncher
    Start-Class: top.wisely.springasync.SpringAsyncApplication
    Spring-Boot-Version: 2.7.2
    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
    
  3. Main-Class: org.springframework.boot.loader.JarLauncher is the main entry point. JarLauncher

  4. BecauseJarLauncher extends ExecutableArchiveLauncher and ExecutableArchiveLauncher extends Launcher

  5. JarLauncher's main method:

    public class JarLauncher extends ExecutableArchiveLauncher {
    //...
     public static void main(String[] args) throws Exception {
         new JarLauncher().launch(args);
     }
    //...
    }
    
  6. So the real launch(args) method is in Launcher class:
    public abstract class Launcher {
     protected void launch(String[] args) throws Exception {
        if (!isExploded()) {
            JarFile.registerUrlProtocolHandler(); 
        }
        ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator()); //①
        String jarMode = System.getProperty("jarmode"); 
        String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass(); //②
        launch(args, launchClass, classLoader);  //③
    }
    }
    

① : classLoader - Create a new LaunchedURLClassLoader instance. all BOOT-INF/classes and BOOT-INF/jar classes are loaded by LaunchedURLClassLoader .

② : launchClass - get the Start-Class from META-INF/MANIFEST.MF.

③:launch Application using args,launchClass,classLoader.

That'a all for my first English article.

More from this blog

用Java 17的Records加速Spring Boot开发

在《Spring Boot 2.6新特性:使用Java 17的Record作为配置属性》,我们提到了使用Java Records来作为Spring Boot的配置属性(configuration properties),从而减少了大量样板代码的编写,我们本篇将进一步拓展Records在Spring Boot下的应用场景,从而进一步减少我们的样板代码,使代码看上去更简洁清晰。 1、什么是Records record是一种特殊类型的类声明,目的是为了减少样板代码。record引入的主要目的是快速创...

Nov 11, 2022
用Java 17的Records加速Spring Boot开发

Spring Boot 2.6新特性:使用Java 17的Record作为配置属性

Spring Boot 3.0的基线版本是Java 17,Spring Boot 3.0版本将全面对Java 17的支持。较新版本的2.x的Spring Boot版本也可以使用Java 17的特性。 本文介绍Spring Boot 2.6对Java 17支持的一个新特性,使用Java 17的Record来做为Spring Boot的配置属性(ConfiguartionProperties)。 什么是Record record是一种特殊类型的类声明,目的是为了减少样板代码。record引入的主要目...

Nov 3, 2022
Spring Boot 2.6新特性:使用Java 17的Record作为配置属性

使用Gradle全面加速Spring Boot开发

大家都知道Gradle和Maven一样,是一个项目的构建工具。它通过任务来控制开发的进程,这些任务包括:编译、打包、测试、部署和发布等。Gradle诞生于2008年,仅仅比Maven晚4年。Android也采用Gradle作为默认的构建工具。 本文期望通过以下的讲述,帮助你快速轻松的使用Gradle加速您的Spring Boot开发应用。 1、Gradle越来越流行 2012年开始,Spring框架已全部使用Gradle来构建;2020年开始,Spring Boot也全部采用Gradle来构建...

Oct 31, 2022
使用Gradle全面加速Spring Boot开发

Spring/Spring Boot下如何动态配置计划任务

在Spring/Spring Boot下实现计划任务是很简单的,我们只需通过@EnableScheduling 开启计划任务的支持,然后通过@Scheduled 注解来制定计划任务,这样的实现解决了我们对计划任务的绝大部分需求。 但在很多时候,通过上述方式实现的计划任务是在代码里写死的,我们需要修改计划任务只能通过修改代码的方式实现。很多时候,我们需要从外部来设置计划任务执行的时间和方式。所以在本文中,我们着重讲解一下如何动态地配置计划任务。 和Spring对异步任务的支持一样,通过@Enabl...

Oct 29, 2022
Spring/Spring Boot下如何动态配置计划任务

Spring 6/Spring Boot 3新特性:优雅的业务异常处理

当你使用Spring Boot(Spring MVC)进行RESTful API开发的时候,你会发现HTTP的状态码很多时候不能足够有效的传递错误的信息。 HTTP里有一个RFC 7807规范:https://www.rfc-editor.org/rfc/rfc7807。这个规范里定义了HTTP API的“问题细节”(Problem Details)内容。 该规范定义了一个“问题细节”(Problem Details),用它来携带HTTP错误返回信息,避免自定义新的错误返回格式。我们通常情况下是...

Oct 28, 2022
Spring 6/Spring Boot 3新特性:优雅的业务异常处理

汪云飞的工具箱

24 posts