You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:用jdeps和jlink构建Spring Boot自定义JRE遇异常问题

问题描述

我正尝试为我的Spring Boot应用构建自定义JRE,为此编写了Dockerfile,先运行jdeps再组装JRE。以下是我的Dockerfile代码:

ARG ALPINE_VERSION=3.18.5
ARG JAVA_VERSION=21.0.1
FROM azul/zulu-openjdk-alpine:${JAVA_VERSION} AS builder
WORKDIR /build
USER root
COPY build/libs/pet-service.jar application.jar
RUN apk add --no-cache binutils --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main/ \
    && jdeps --ignore-missing-deps -q --recursive --multi-release 21 --print-module-deps application.jar > deps.info \
    && cat deps.info \
    && jlink  --add-modules ${cat deps.info} --strip-debug --no-header-files --no-man-pages --output /myjre \
    && java -Djarmode=layertools -jar application.jar extract \
    && chown -R 1001:1001 .

FROM alpine:${ALPINE_VERSION}
ENV JAVA_HOME /user/java/jdk21
ENV PATH $JAVA_HOME/bin:$PATH
COPY --from=builder /myjre $JAVA_HOME
WORKDIR /application
COPY --from=builder /build/agent/ ./
COPY --from=builder /build/dependencies/ ./
COPY --from=builder /build/snapshot-dependencies/ ./
COPY --from=builder /build/spring-boot-loader/ ./
COPY --from=builder /build/application/ ./
USER 1001
ENV JAVA_OPTS ''
ENV MAIN_OPTS ''
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} org.springframework.boot.loader.launch.JarLauncher ${MAIN_OPTS}"]
EXPOSE 8080

但jdeps仅识别出java.base,运行该Docker镜像时出现PropertyEditorSupporter类找不到的错误。当我不使用jdeps结果,手动添加java.base和java.desktop模块后,运行镜像时会很快停止,且无任何日志或错误输出。另外我使用了内部镜像仓库,调整后的镜像链接可能无法正常使用,但在本地环境是可行的。

解决方案

1. 修复jlink的变量引用错误

Dockerfile中jlink命令里的${cat deps.info}是错误的Shell语法,无法读取文件内容,应该替换为$(cat deps.info)。这个错误直接导致jlink没有加载jdeps分析出的依赖,最终只生成了仅含java.base的JRE。

修改后的RUN命令中jlink部分:

jlink --add-modules $(cat deps.info) --strip-debug --no-header-files --no-man-pages --output /myjre

2. 优化jdeps分析参数

Spring Boot大量使用反射,jdeps默认分析无法完全识别所有依赖模块,可补充参数提升准确性:

  • 添加--verbose输出详细依赖,定位缺失模块
  • 手动补充Spring常用模块:java.desktop(包含PropertyEditorSupporter)、java.sql、java.naming等,这些模块常被框架用到但jdeps无法自动识别

调整后的jdeps命令示例:

jdeps --ignore-missing-deps --recursive --multi-release 21 --print-module-deps --verbose application.jar > deps.info

3. 排查无日志启动失败问题

手动添加模块后启动即停止,可通过以下方式排查:

  • 临时修改ENTRYPOINT进入容器排查环境:
    ENTRYPOINT ["sh"]
    
    进入容器后检查JAVA_HOME配置、java命令可用性、应用文件是否完整复制到/application目录。
  • 在JAVA_OPTS中添加日志调试参数:-Dlogging.level.root=DEBUG,强制输出启动日志。
  • 检查权限:在builder阶段添加chmod -R 755 /build,确保1001用户对应用文件有读取权限。

4. 验证分层构建完整性

确认Spring Boot layertools拆分的所有目录都已正确复制到最终镜像的/application目录,避免因文件缺失导致启动失败。

内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:20:20