嵌套 JARs
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/
目录下包含额外的索引文件。
可以为 jar 和 war 提供 classpath.idx
文件,它提供了应该添加到类路径的 jar 的顺序。
layers.idx
文件只能用于 jar,它允许将 jar 分割成逻辑层以用于 Docker/OCI 镜像创建。
索引文件遵循 YAML 兼容的语法,以便第三方工具可以轻松解析。 但是,这些文件在内部并不作为 YAML 解析,它们必须严格按照下面描述的格式编写才能使用。
类路径索引
类路径索引文件可以在 BOOT-INF/classpath.idx
中提供。
通常,它是由 Spring Boot 的 Maven 和 Gradle 构建插件自动生成的。
它提供了应该添加到类路径的 jar 名称(包括目录)的列表,按顺序排列。
当由构建插件生成时,此类路径顺序与构建系统用于运行和测试应用程序的顺序相匹配。
每行必须以破折号空格("-·"
)开头,名称必须用双引号括起来。
例如,给定以下 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 文件时使用类路径索引文件。
在从 IDE 运行应用程序或使用 Maven 的 spring-boot:run
或 Gradle 的 bootRun
时不会使用它。
注意:启用可重现构建时,类路径索引文件中的条目按字母顺序排序。
层索引
层索引文件可以在 BOOT-INF/layers.idx
中提供。
它提供了层列表和应该包含在其中的 jar 部分。
层按照应该添加到 Docker/OCI 镜像的顺序编写。
层名称作为带破折号空格("-·"
)前缀和冒号(":"
)后缀的带引号字符串编写。
层内容是作为带空格空格破折号空格("··-·"
)前缀的带引号字符串编写的文件名或目录名。
目录名以 /
结尾,文件名不以 /
结尾。
当使用目录名时,意味着该目录内的所有文件都在同一层中。
层索引的典型示例如下:
- "dependencies":
- "BOOT-INF/lib/dependency1.jar"
- "BOOT-INF/lib/dependency2.jar"
- "application":
- "BOOT-INF/classes/"
- "META-INF/"