Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

helidon se 4 native-image build error: HelidonFlavor was found in the image heap. #8726

Closed
daggerok opened this issue May 4, 2024 · 2 comments · Fixed by #9028
Closed

helidon se 4 native-image build error: HelidonFlavor was found in the image heap. #8726

daggerok opened this issue May 4, 2024 · 2 comments · Fixed by #9028
Assignees
Labels
4.x Version 4.x bug Something isn't working linux native-image SE
Milestone

Comments

@daggerok
Copy link

daggerok commented May 4, 2024

Environment Details

  • Helidon Version: 4.0.8
  • Helidon SE
  • JDK version: GraalVM 22
  • OS: ubuntu-latest (GitHub Actions)

Problem Description

I have a simple helidon se 4 app. On my mac locally native-image maven profile can be built successfully so I can run and test the app, but not in GitHub Actions. I also tried to use macos-latest in Github Actions, but was not success with native-image maven profile build

Recommended fix:

include '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor' in your configuration.

also doesn't helped

error

[INFO] --- native:0.9.27:generateResourceConfig (resource-config) @ app-02-hello-helidon-se-4-java22 ---
[INFO] Detected resources for /home/runner/work/bidder/bidder/apps/app-02-hello-helidon-se-4-java22/target/app-02-hello-helidon-se-4-java22.jar are [application.yaml, logging.properties, META-INF/native-image/io/github/daggerok/bidder/app-02-hello-helidon-se-4-java22/native-image.properties, META-INF/maven/io.github.daggerok.bidder/app-02-hello-helidon-se-4-java22/pom.xml, META-INF/maven/io.github.daggerok.bidder/app-02-hello-helidon-se-4-java22/pom.properties]
[INFO] Resources configuration written into /home/runner/work/bidder/bidder/apps/app-02-hello-helidon-se-4-java22/target/native/generated/generateResourceConfig/resource-config.json
[INFO] 
[INFO] <<< native:0.9.27:compile (build-native-image) < package @ app-02-hello-helidon-se-4-java22 <<<
[INFO] 
[INFO] 
[INFO] --- native:0.9.27:compile (build-native-image) @ app-02-hello-helidon-se-4-java22 ---
[INFO] Found GraalVM installation from GRAALVM_HOME variable.
Warning:  Properties file at 'jar:file:///home/runner/.m2/repository/io/helidon/common/helidon-common-key-util/4.0.8/helidon-common-key-util-4.0.8.jar!/META-INF/native-image/io.helidon.common.pki/helidon-common-pki/native-image.properties' does not match the recommended 'META-INF/native-image/io.helidon.common/helidon-common-key-util/native-image.properties' layout.
[INFO] Executing: /opt/hostedtoolcache/graalvm-jdk-22_linux-x64_bin/22.0.0/x64/graalvm-jdk-22.0.1+8.1/bin/native-image @target/tmp/native-image-15730015647527423427.args io.github.daggerok.hello.Main
Warning: The option '-H:ReflectionConfigurationResources=META-INF/native-image/io.micrometer/micrometer-core/reflect-config.json' is experimental and must be enabled via '-H:+UnlockExperimentalVMOptions' in the future.
Warning: Please re-evaluate whether any experimental option is required, and either remove or unlock it. The build output lists all active experimental options, including where they come from and possible alternatives. If you think an experimental option should be considered as stable, please file an issue.
========================================================================================================================
GraalVM Native Image: Generating 'app-02-hello-helidon-se-4-java22' (executable)...
========================================================================================================================
For detailed information and explanations on the build output, visit:
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
------------------------------------------------------------------------------------------------------------------------
2024.05.04 21:38:26.890 Logging at initialization configured using classpath: /logging.properties
[1/8] Initializing...                                                                                   (11.0s @ 0.09GB)
 Java version: 22.0.1+8, vendor version: Oracle GraalVM 22.0.1+8.1
 Graal compiler: optimization level: 2, target machine: x86-64-v3, PGO: ML-inferred
 C compiler: gcc (linux, x86_64, 11.4.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 2 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
 - io.helidon.integrations.graal.nativeimage.extension.HelidonReflectionFeature
------------------------------------------------------------------------------------------------------------------------
 1 experimental option(s) unlocked:
 - '-H:ReflectionConfigurationResources': Use a reflect-config.json in your META-INF/native-image/<groupID>/<artifactID> directory instead. (origin(s): 'META-INF/native-image/io.micrometer/micrometer-core/native-image.properties' in 'file:///home/runner/.m2/repository/io/micrometer/micrometer-core/1.11.3/micrometer-core-1.11.3.jar')
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 5.85GB of memory (75.6% of 7.74GB system memory, determined at start)
 - 2 thread(s) (100.0% of 2 available processor(s), determined at start)
[2/8] Performing analysis...  []                                                                        (38.4s @ 0.34GB)
    4,109 reachable types   (72.3% of    5,[684](https://github.com/daggerok/bidder/actions/runs/8953420571/job/24591903356#step:7:685) total)
    4,699 reachable fields  (44.2% of   10,628 total)
   18,450 reachable methods (44.6% of   41,407 total)
    1,309 types,    61 fields, and 1,058 methods registered for reflection

Error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: An object of type 'io.helidon.common.features.api.HelidonFlavor' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'io.helidon.common.features.api.HelidonFlavor' are persisted in the image heap, add 

    '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor'
------------------------------------------------------------------------------------------------------------------------

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'io.helidon.common.features.api.HelidonFlavor' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.
                        4.0s (7.5% of total time) in 93 GCs | Peak RSS: 0.87GB | CPU load: 1.93

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=io.helidon.common.features.api.HelidonFlavor'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Object was reached by
  manually created constant
Error: java.util.concurrent.ExecutionException: com.oracle.graal.pointsto.util.AnalysisError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: An object of type 'io.helidon.common.features.api.HelidonFlavor' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'io.helidon.common.features.api.HelidonFlavor' are persisted in the image heap, add 

    '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'io.helidon.common.features.api.HelidonFlavor' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=io.helidon.common.features.api.HelidonFlavor'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Object was reached by
  manually created constant
Error: java.util.concurrent.ExecutionException: com.oracle.graal.pointsto.util.AnalysisError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: An object of type 'io.helidon.common.features.api.HelidonFlavor' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'io.helidon.common.features.api.HelidonFlavor' are persisted in the image heap, add 

    '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'io.helidon.common.features.api.HelidonFlavor' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=io.helidon.common.features.api.HelidonFlavor'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=io.helidon.common.features.api.HelidonFlavor' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Object was reached by
  manually created constant
========================================================================================================================
Failed generating 'app-02-hello-helidon-se-4-java22' after 51.3s.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:01 min
[INFO] Finished at: 2024-05-04T21:39:13Z
[INFO] ------------------------------------------------------------------------
Error:  Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.27:compile (build-native-image) on project app-02-hello-helidon-se-4-java22: Execution of /opt/hostedtoolcache/graalvm-jdk-22_linux-x64_bin/22.0.0/x64/graalvm-jdk-22.0.1+8.1/bin/native-image @target/tmp/native-image-15[730](https://github.com/daggerok/bidder/actions/runs/8953420571/job/24591903356#step:7:731)015647527423427.args io.github.daggerok.hello.Main returned non-zero result -> [Help 1]
Error:  
Error:  To see the full stack trace of the errors, re-run Maven with the -e switch.
Error:  Re-run Maven using the -X switch to enable full debug logging.
Error:  
Error:  For more information about the errors and possible solutions, please read the following articles:
Error:  [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
Error: Process completed with exit code 1.

Steps to reproduce

Main.java

@Log
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Main {

    public static void main(String[] args) {
        Locale.setDefault(Locale.US);
        TimeZone.setDefault(TimeZone.getTimeZone(ZoneOffset.UTC));

        LogConfig.configureRuntime();

        var config = Config.create();
        Config.global(config);

        var server = WebServer.builder()
                .config(config.get("server")) // see application.yaml file
                .routing(Main::routing)
                .build()
                .start();

        log.info("WEB server is up! http://localhost:%d/hello%n".formatted(server.port()));
    }

    private static void routing(HttpRouting.Builder builder) {
        var greeting = Config.global().get("app.greeting").as(String.class).get();
        builder.get("/hello", (req, res) -> res.send(Map.of(greeting, "World")));
    }
}

src/main/resources/META-INF/native-image/.../native-image.properties

Args=--initialize-at-build-time=io.github.daggerok.hello

application.yaml

server:
  port: 8080
  host: 0.0.0.0

app:
  greeting: "Hello"

and github action (see https://www.graalvm.org/downloads/):

  app-02-hello-helidon-se-4-java22:
    strategy:
      matrix:
        java: [22]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: graalvm/setup-graalvm@v1
        with:
          distribution: 'graalvm'
          java-version: ${{ matrix.java }}
      - run: sudo apt install -yqq httpie
      - run: ./mvnw -f apps/app-02-hello-helidon-se-4-java22 clean package -Pnative-image # <-- failed here
      - run: ./apps/app-02-hello-helidon-se-4-java22/target/app-02-hello-helidon-se-4-java22 &
      - run: http --ignore-stdin :8080/hello

pom.xml

    <parent>
        <groupId>io.helidon.applications</groupId>
        <artifactId>helidon-se</artifactId>
        <version>4.0.8</version>
        <relativePath/>
    </parent>
    <!-- ...skipped -->
    <properties>
        <encoding>UTF-8</encoding>
        <java.version>21</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>${encoding}</project.build.sourceEncoding>
        <native.image.reportExceptionStackTraces>true</native.image.reportExceptionStackTraces>
        <jlink.image.addClassDataSharingArchive>false</jlink.image.addClassDataSharingArchive>
        <mainClass>io.github.daggerok.hello.Main</mainClass>
        <lombok.version>1.18.32</lombok.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <optional>true</optional>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.helidon.webserver</groupId>
            <artifactId>helidon-webserver</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.config</groupId>
            <artifactId>helidon-config-yaml</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.webserver.observe</groupId>
            <artifactId>helidon-webserver-observe-health</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.health</groupId>
            <artifactId>helidon-health-checks</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.http.media</groupId>
            <artifactId>helidon-http-media-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.logging</groupId>
            <artifactId>helidon-logging-jul</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.helidon.webserver.observe</groupId>
            <artifactId>helidon-webserver-observe-metrics</artifactId>
        </dependency>
        <dependency>
            <groupId>io.helidon.metrics</groupId>
            <artifactId>helidon-metrics-system-meters</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.helidon.webclient</groupId>
            <artifactId>helidon-webclient</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.helidon.webserver.testing.junit5</groupId>
            <artifactId>helidon-webserver-testing-junit5</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-libs</id>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
@romain-grecourt romain-grecourt added SE native-image 4.x Version 4.x bug Something isn't working linux labels May 6, 2024
@barchetta barchetta added this to the 4.0.9 milestone May 6, 2024
@barchetta barchetta modified the milestones: 4.0.9, 4.1.0 May 24, 2024
@tomas-langer
Copy link
Member

The reason: GraalVM native image analysis is improving with each version, catching additional instances that are in the memory at time of the build. This causes errors such as the one above. In previous versions of GraalVM, this is not discovered.
The solution:

  • add initialization at build time for features
  • add initialization at build time for logging (as we use logging both at build time and at runtime)

After fixing these two issues, the build passes (PR to come soon)

@daggerok
Copy link
Author

@tomas-langer

add initialization at build time for features
add initialization at build time for logging (as we use logging both at build time and at runtime)

where can I read more about it? or maybe can you give some github link with example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.x Version 4.x bug Something isn't working linux native-image SE
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants