Spring Boot 3.1.5配置GraalVM原生镜像替换OpenJDK发行版问题
我基于Spring Boot 3.1.5、Java 21,尝试通过GraalVM和Spring Boot Buildpacks构建Native镜像。已配置spring-boot-maven-plugin并添加BP_NATIVE_IMAGE环境变量启用原生镜像,为替换默认的BellSoft Liberica,手动指定了Adoptium(Eclipse Temurin)相关的Buildpacks,配置如下:
<build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> <image> <builder>paketobuildpacks/builder-jammy-tiny</builder> <createdDate>${createdDate}</createdDate> <env> <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE> </env> <buildpacks> <buildpack>gcr.io/paketo-buildpacks/ca-certificates:latest</buildpack> <buildpack>gcr.io/paketo-buildpacks/adoptium:latest</buildpack> <buildpack>gcr.io/paketo-buildpacks/syft:latest</buildpack> <buildpack>gcr.io/paketo-buildpacks/executable-jar:latest</buildpack> <buildpack>gcr.io/paketo-buildpacks/dist-zip:latest</buildpack> <buildpack>gcr.io/paketo-buildpacks/spring-boot:latest</buildpack> </buildpacks> </image> </configuration> </plugin> </plugins> </build>
移除Buildpacks列表时可正常构建,参与构建的Buildpacks如下:
[INFO] [creator] 6 of 15 buildpacks participating [INFO] [creator] paketo-buildpacks/ca-certificates 3.6.6 [INFO] [creator] paketo-buildpacks/bellsoft-liberica 10.4.2 [INFO] [creator] paketo-buildpacks/syft 1.39.0 [INFO] [creator] paketo-buildpacks/executable-jar 6.8.2 [INFO] [creator] paketo-buildpacks/spring-boot 5.27.5 [INFO] [creator] paketo-buildpacks/native-image 5.12.6
但手动添加native-image Buildpack后构建失败,报错:
[INFO] [creator] no valid dependencies for native-image-svm, 21, and io.buildpacks.stacks.jammy.tiny in [(jdk, 8.0.392, [*]) (jre, 8.0.392, [*]) (jdk, 11.0.21, [*]) (jre, 11.0.21, [*]) (jdk, 17.0.9, [*]) (jre, 17.0.9, [*]) (jdk, 21.0.1, [*]) (jre, 21.0.1, [*])]
将adoptium:latest替换为bellsoft-liberica:latest或graalvm:latest则可正常构建。此外还有两个疑问:
- 使用BellSoft Liberica构建原生镜像时,构建过程中是否未使用BellSoft Liberica OpenJDK?
- 为何使用GraalVM作为OpenJDK发行版时Docker镜像大小达650MB,而使用BellSoft Liberica时仅85MB?
一、Adoptium构建失败原因
Paketo的native-image Buildpack依赖JDK包含GraalVM Substrate VM(SVM)组件,而Adoptium OpenJDK默认不自带该组件。BellSoft Liberica提供了集成GraalVM SVM的Native Image Kit(NIK)变体,GraalVM发行版本身原生支持SVM,因此替换后能正常构建。
目前官方Paketo生态中,Adoptium Buildpack未集成GraalVM SVM,无法直接配合native-image Buildpack使用,若要使用Adoptium需自定义Buildpack引入SVM组件。
二、BellSoft Liberica构建时的JDK使用说明
构建过程中确实使用了BellSoft Liberica OpenJDK。Paketo的bellsoft-liberica Buildpack会自动拉取包含GraalVM SVM的Liberica NIK,该套件基于Liberica JDK,包含构建Native镜像所需的全套工具链,构建阶段全程使用Liberica的JDK环境。
三、镜像大小差异原因
- GraalVM发行版镜像:指定
graalvm:latest时,Buildpack会将完整的GraalVM JDK环境打包进镜像(即使是原生镜像场景,部分情况下会保留JDK运行时),加上GraalVM本身体积较大,最终镜像达650MB。 - BellSoft Liberica镜像:使用
bellsoft-libericaBuildpack构建时,借助Liberica NIK完成编译后,Buildpack会自动清理构建阶段的JDK环境,最终镜像仅包含编译好的Native可执行文件和jammy-tiny栈的最小系统依赖,因此体积仅85MB。
内容的提问来源于stack exchange,提问作者DJViking

