嵌套JAR包

Java 并未提供任何标准方式来加载嵌套的 jar 文件(即,jar 文件本身包含在另一个 jar 内部)。 如果你需要分发一个可以直接从命令行运行、无需解压的自包含应用,这会带来一些问题。

为了解决这个问题,许多开发者会使用“shaded” jar。 shaded jar 会将所有 jar 中的所有类打包到一个“uber jar”中。 shaded jar 的问题在于很难看清你的应用实际包含了哪些库。 如果多个 jar 中存在相同文件名但内容不同,也会带来麻烦。 Spring Boot 采用了不同的方式,允许你直接嵌套 jar 包。

可执行Jar文件结构

Spring Boot Loader 兼容的 jar 文件应按如下方式组织:

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/classes 目录下。 依赖应放在嵌套的 BOOT-INF/lib 目录下。

可执行War文件结构

Spring Boot Loader 兼容的 war 文件应按如下方式组织:

example.war
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-WEB-INF
    +-classes
    |  +-com
    |     +-mycompany
    |        +-project
    |           +-YourClasses.class
    +-lib
    |  +-dependency1.jar
    |  +-dependency2.jar
    +-lib-provided
       +-servlet-api.jar
       +-dependency3.jar

依赖应放在嵌套的 WEB-INF/lib 目录下。 运行于嵌入式环境但在传统 Web 容器部署时不需要的依赖,应放在 WEB-INF/lib-provided 目录下。

索引文件

Spring Boot Loader 兼容的 jar 和 war 包可以在 BOOT-INF/ 目录下包含额外的索引文件。 classpath.idx 文件可用于 jar 和 war,指定 jar 应添加到 classpath 的顺序。 layers.idx 文件仅用于 jar,允许将 jar 拆分为逻辑层以用于 Docker/OCI 镜像构建。

索引文件采用 YAML 兼容语法,便于第三方工具解析。 但这些文件 不会 被内部当作 YAML 解析,必须严格按照下述格式编写才能被使用。

Classpath 索引

classpath 索引文件可放在 BOOT-INF/classpath.idx。 通常由 Spring Boot 的 Maven 和 Gradle 构建插件自动生成。 它提供了 jar 名称(包含目录)的列表,按应添加到 classpath 的顺序排列。 由构建插件生成时,这个 classpath 顺序与构建系统运行和测试应用时一致。 每一行必须以短横加空格("-·")开头,名称必须用双引号括起来。

例如,给定如下 jar:

example.jar
 |
 +-META-INF
 |  +-...
 +-BOOT-INF
    +-classes
    |  +...
    +-lib
       +-dependency1.jar
       +-dependency2.jar

索引文件如下所示:

- "BOOT-INF/lib/dependency2.jar"
- "BOOT-INF/lib/dependency1.jar"
Spring Boot 仅在使用 java -jar 执行 jar 或 war 文件时才会使用 classpath 索引文件。 在 IDE 运行应用或使用 Maven 的 spring-boot:run 或 Gradle 的 bootRun 时不会使用。
启用可重现构建时,classpath 索引文件中的条目会按字母顺序排序。

Layer 索引

layers 索引文件可放在 BOOT-INF/layers.idx。 它提供了各层及应包含在其中的 jar 部分的列表。 层按应添加到 Docker/OCI 镜像的顺序书写。 层名为带短横加空格("-·“)前缀和冒号(”:")后缀的带引号字符串。 层内容为带空格空格短横空格("··-·")前缀的带引号字符串,表示文件或目录名。 目录名以 / 结尾,文件名则否。 使用目录名时,表示该目录下所有文件都在同一层。

一个典型的 layers 索引示例:

- "dependencies":
  - "BOOT-INF/lib/dependency1.jar"
  - "BOOT-INF/lib/dependency2.jar"
- "application":
  - "BOOT-INF/classes/"
  - "META-INF/"