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

Spring Boot Native构建Docker镜像无法访问src/main/resources文件

问题:Spring Boot Native Docker镜像无法读取resources下的文件

背景

目标是构建一个可读取src/main/resources目录下文件的Spring Boot Native应用。

pom.xml配置

<properties>
    <java.version>17</java.version>
</properties>
<build>
    <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>
                <image>
                    <env>
                        <!-- 确保`mvn spring-boot:build-image`使用项目定义的Java版本 -->
                        <BP_JVM_VERSION>${java.version}</BP_JVM_VERSION>
<!-- 未闭合标签 -->

    <profiles>
        <!-- mvn [goal] -Pnative -->
        <profile>
            <id>native</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>build-native</id>
                                <goals>
                                    <goal>compile-no-fork</goal>
                                </goals>
                                <phase>package</phase>
                                <configuration>
                                    <!-- Native镜像默认不包含资源,因此添加该配置 -->
                                    <buildArgs>-H:IncludeResources=.*txt$</buildArgs>
<!-- 未闭合标签 -->

文件读取代码

private static Stream<String> readFileFromResourcesDirectory(String filename) {
        String fileString;
        try (InputStream inputStream = DemoController.class.getClassLoader()
                                                           .getResourceAsStream(filename)) {
            if (inputStream == null) throw new Exception("Can't find file " + filename + " in /resources.");
            fileString = IOUtils.toString(inputStream, UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Issue reading or parsing file " + filename + "\n" + e.getMessage());
        }
        return Arrays.stream(fileString.split("\n"));
    }

异常信息

运行mvn spring-boot:build-image -Pnative构建的Docker镜像时触发异常:

java.lang.RuntimeException: Issue reading or parsing file foo.txt
Can't find file foo.txt in /resources.

测试结果

  • 未使用-Pnative构建的Docker镜像运行正常
  • 使用mvn package -Pnative构建的本地Native可执行文件运行正常
  • 使用-Pnative构建的Docker镜像运行异常

镜像构建日志片段

日志显示本地Native构建已执行指定参数:

[INFO] Executing: /home/tco/graalvm/graalvm-ce-java17-22.3.1/bin/native-image (...) -H:IncludeResources=.*txt$

原因分析与解决方案

原因

你在native-maven-plugin的native profile中配置的-H:IncludeResources=.*txt$仅对本地Native可执行文件构建(mvn package -Pnative)生效。但使用spring-boot:build-image -Pnative构建Docker镜像时,Spring Boot的Buildpacks构建流程不会复用该配置,导致镜像内的Native可执行文件未包含指定的txt资源。

解决方案

需要通过spring-boot-maven-plugin的image配置,将Native Image构建参数传递给Docker构建流程,具体是添加BP_NATIVE_IMAGE_BUILD_ARGUMENTS环境变量:

修改spring-boot-maven-plugin的配置部分:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <image>
            <env>
                <!-- 确保构建镜像使用项目定义的Java版本 -->
                <BP_JVM_VERSION>${java.version}</BP_JVM_VERSION>
                <!-- 传递Native Image构建参数,包含所有txt后缀的资源 -->
                <BP_NATIVE_IMAGE_BUILD_ARGUMENTS>-H:IncludeResources=.*txt$</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
            </env>
        </image>
    </configuration>
</plugin>

BP_NATIVE_IMAGE_BUILD_ARGUMENTS是Spring Boot Buildpacks专门用于传递Native Image构建参数的环境变量,配置后Docker镜像构建过程会自动将该参数传给GraalVM的native-image命令,确保txt资源被正确包含到镜像内的可执行文件中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:24:57