0

My goal is to build a Spring Boot Native app that reads a file in src/main/resources.

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>
                            <!-- Make sure `mvn spring-boot:build-image` uses the Java version defined in this project -->
                            <BP_JVM_VERSION>${java.version}</BP_JVM_VERSION>
<!-- closing tags -->

    <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>
                                    <!-- Because native image doesn't include resources by default -->
                                    <buildArgs>-H:IncludeResources=.*txt$</buildArgs>
<!-- closing tags -->

Code that accesses the files in src/main/resources/:

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"));
    }

The image is built with mvn spring-boot:build-image -Pnative.

After running the Docker image, reaching the code triggers this exception:

java.lang.RuntimeException: Issue reading or parsing file foo.txt
Can't find file foo.txt in /resources.
  • It works fine with a Docker image built without -Pnative
  • It works fine with a native executable built with mvn package -Pnative
  • It doesn't work with a Docker image built with -Pnative

Why is that ?

Found in the image build log with -Pnative:

[INFO] Executing: /home/tco/graalvm/graalvm-ce-java17-22.3.1/bin/native-image (...) -H:IncludeResources=.*txt$
ThCollignon
  • 976
  • 3
  • 14
  • 31
  • Same issue when using `this.getClass().getResourceAsStream()` – ThCollignon May 03 '23 at 07:09
  • [Related question (duplicate?)](https://stackoverflow.com/questions/66157879/running-spring-boot-native-application-cannot-load-resource-file) – ThCollignon May 03 '23 at 07:39
  • I still don't know why it doesn't work with `-H:IncludeResources=.*txt$`, but as a workaround I could make it work with `hints.resources().registerPattern("*.txt");`, from [GraalVM Native Image Support doc](https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.advanced.custom-hints) – ThCollignon May 03 '23 at 12:05

0 Answers0