oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
19.97k stars 1.6k forks source link

[GR-49845] Native-Image build fails after upgrading vom GraalVM 20 to GraalVM 21 #7471

Open Rottinator opened 9 months ago

Rottinator commented 9 months ago

Hello guys,

today i've updated one of my projects from version 20 to 21, tried to build and execute, but the native image build failed. The error i am getting is:

Fatal error: java.lang.LayerInstantiationException: Class loader (instance of): com.oracle.svm.hosted.NativeImageClassLoader @6fc6f14e tried to define prohibited package name: java.net.http
    at java.base/java.lang.ModuleLayer.defineModules(ModuleLayer.java:704)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageClassLoaderSupport.<init>(NativeImageClassLoaderSupport.java:177)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.installNativeImageClassLoader(NativeImageGeneratorRunner.java:274)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.start(NativeImageGeneratorRunner.java:132)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:97)

I am using java modules and one of my modules requires java.net.http to use the HttpClient class (thats all relations i have to the module java.net.http named in the error message).

My plattform: Windows 10 x64 GraalVM version: 21+35.1 C++ compiler: MSVC\14.35.32215 (from Visual Studio Community Edition 2022)

Sadly i can not reproduce this issue, when building a sample Hello World app, consuming the java.net.http package. Is there any way to get a more detailled log/stack-trace to help you analyse this issue or do you already know what can be the issue with the error message i provided? If you need more information please let me know.

Best regards Christoph

oubidar-Abderrahim commented 9 months ago

Hi, Thank you for reaching out. Unfortunately, with the stack trace alone, we cannot determine the cause of this issue. If you can provide a reproducer to this, we can investigate the issue further. if not, you may want to consider sharing this on the community slack for GraalVM to see if someone has seen this issue before

Rottinator commented 9 months ago

Hi @oubidar-Abderrahim Sharing the issue in slack was the first thing i did after encountering the problem. @fniephaus told me, to open an issue cause it looks like a bug. Unfortunately i could not reproduce this issue in a simple demo environment, and my environment is hard to share, cause i use a some external dependencies and some dependencies that are not public available on maven repository.

Are there any additional flags i can add to the native image execution, to spit out more debug information that can help you analyzing the issue? Or could you provide me more information at which step native image is crashing, what it is currently trying to do, so i can maybe isolate the problem to reproduce it easier.

Rottinator commented 9 months ago

Hi, after 2 hours of playing around with the native-image arguments, i finally could reproduce the issue and find a workaround. The issue happens, when building a module project only with the arguments "--module-path" and "--module". For whatever reason, when i add the "--module-path" also on the "--class-path" the build runs without a problem.

So a very small simple application that looks like the following can reproduce the issue:

module-info.java

module graalvmmodulesample {
    requires java.net.http;

    exports de.example.graalvmmodulesample;
}

Application.java

package de.example.graalvmmodulesample;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class Application {
    public static void main(String[] args) throws Exception {
            HttpClient httpClient = HttpClient.newBuilder().build();

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://www.google.de"))
                .build();

            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));

            System.out.println(response.body());
    }
}

native-image-arguments crashing with the exception

-o C:\\dev\\temp\\graalvm-module-sample\\target\\module-sample
--module-path "C:/dev/temp/graalvm-module-sample/target/graalvm-module-sample-1.0-SNAPSHOT.jar"
--module graalvmmodulesample/de.example.graalvmmodulesample.Application

native-image-arguments working and not crashing with an exception

-o C:\\dev\\temp\\graalvm-module-sample\\target\\module-sample
--module-path "C:/dev/temp/graalvm-module-sample/target/graalvm-module-sample-1.0-SNAPSHOT.jar"
--module graalvmmodulesample/de.example.graalvmmodulesample.Application
--class-path "C:/dev/temp/graalvm-module-sample/target/graalvm-module-sample-1.0-SNAPSHOT.jar"

So i think when you do this sample https://www.graalvm.org/latest/reference-manual/native-image/guides/build-java-modules-into-native-executable/ add a reference and code to access java.net.http and build it manually with the native-image command described in the tutorial, the build should fail.

oubidar-Abderrahim commented 8 months ago

Thank you for sharing your findings, could you please make the steps a bit more clear? please share the full code, plus the compilation and building commands for both the case that works and the one that doesn't.

Rottinator commented 8 months ago

Hi,

as i already wrote, it is enough to download the sample of your documentation and add a requires into the module-info.java and build it with java 21.

Step 1 - Clone the repo

 git clone https://github.com/graalvm/graalvm-demos
 cd graalvm-demos/native-hello-module

Step 2 - Change the code

pom.xml (Changed to use Java 21)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>HelloModule</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>hello.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Main.java (Unchanged)

package hello;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello from Java Module: " + Main.class.getModule().getName());
    }
}

module-info.java (Added requires to java.net.http)

module HelloModule {
    requires java.net.http;

    exports hello;
}

Step 3 - Build the native-image

mvn clean package
native-image --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule

Hope this helps.

Best regards Christoph

ivan-ristovic commented 3 months ago

This looks like a bug in the synthesis of our internal module layer that we use for the image builder. I managed to reproduce and come up with a simpler (and more proper) workaround:

$ native-image --add-modules=java.net.http --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule

This should give you a workaround until we issue a proper fix.

Rottinator commented 3 months ago

Hi Ivan, the workaround is working fine for me at the moment. Thanks :)

OlexYarm commented 2 days ago

The issue still exists in GraalVM 22.0.1+8.1. Building executable for JavaFX Modular CLI sample application with Oracle GraalVM 22.0.1+8.1 (build 22.0.1+8-jvmci-b01) failed on Windows 11 with error below:

Fatal error: java.lang.LayerInstantiationException: Class loader (instance of): com.oracle.svm.hosted.NativeImageClassLoader @6e0e048a tried to define prohibited package name: java.net.http at java.base/java.lang.ModuleLayer.defineModules(ModuleLayer.java:699) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageClassLoaderSupport.(NativeImageClassLoaderSupport.java:186) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.installNativeImageClassLoader(NativeImageGeneratorRunner.java:273) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.start(NativeImageGeneratorRunner.java:130) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:95) com.oracle.svm.driver.NativeImage$NativeImageError at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.showError(NativeImage.java:2258) at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.build(NativeImage.java:1871) at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.performBuild(NativeImage.java:1830) at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.main(NativeImage.java:1812) at java.base@22.0.1/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

Step to reproduce

  1. Install required software (Oracle GraalVM 22.0.1+8.1, OpenJFX 22 for Windows x64, Git 2.45.x, Git Desktop 2.50.x).
  2. Open Windows Command Prompt
  3. Clone JavaFX samples from GitHub (with Git or Git Desktop) cd / gh repo clone openjfx/samples
  4. Build JavaFX Modular CLI sample application according to README.md cd samples cd CommandLine\Modular\CLI\hellofx set PATH_TO_FX="C:\openjfx-22_windows-x64_bin-sdk\javafx-sdk-22\lib" dir /s /b src*.java > sources.txt & javac --module-path %PATH_TO_FX% -d mods/hellofx @sources.txt & del sources.txt
  5. Run sample application for testing java --module-path "%PATH_TO_FX%;mods" -m hellofx/hellofx.HelloFX
  6. Run sample with GraalVM agent for creating reflection, etc. config files java -agentlib:native-image-agent=config-output-dir=native-image --module-path "%PATH_TO_FX%;mods" -m hellofx/hellofx.HelloFX
  7. Build native image with native-image tool native-image --verbose --native-image-info -H:+UnlockExperimentalVMOptions -H:+BuildReport -g --no-fallback --module-path "%PATH_TO_FX%;mods" -m hellofx/hellofx.HelloFX -o jfxHello

Workaround with parameter --class-path "mods" works for building executable. But executable fails to run as I explained in "Executable for JavaFX Modular CLI sample application built on Windows 11 with GraalVM 22.0.1+8.1 failed to run #9213"

ivan-ristovic commented 2 days ago

Hi @OlexYarm! Thank you for the detailed reproducer. We are tracking this internally as GR-49845.