Skip to content

[Native Image] -H:+AllowJRTFileSystem reads from GraalVM instead of the provided JAVA_HOME #10013

Open
@cushon

Description

@cushon

Describe the Issue

Using -H:+AllowJRTFileSystem creates a native image that reads from the Graal JDK's module files, instead of reading from the provided JAVA_HOME.

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

java version "23.0.1" 2024-10-15
Java(TM) SE Runtime Environment Oracle GraalVM 23.0.1+11.1 (build 23.0.1+11-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 23.0.1+11.1 (build 23.0.1+11-jvmci-b01, mixed mode, sharing)

Operating System and Version

x86_64 GNU/Linux

Diagnostic Flag Confirmation

  • I tried the -H:ThrowMissingRegistrationErrors= flag.

Run Command

./graalvm-jdk-23.0.1+11.1/bin/native-image -H:ThrowMissingRegistrationErrors= --verbose --no-fallback -H:+AllowJRTFileSystem -jar j.jar

Expected Behavior

I expected the native image to use the jrt filesystem to read from the provided JAVA_HOME

Actual Behavior

The native image reads from the JAVA_HOME of the GraalVM used at image built time, and fails if the GraalVM is removed.

Steps to Reproduce

Use this test program:

import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

public class JRTFS {
  public static void main(String[] args) throws IOException {
    String javaHome = args[0];
    FileSystem fileSystem =
        FileSystems.newFileSystem(URI.create("jrt:/"), Map.of("java.home", javaHome));
    Path path = fileSystem.getPath("/modules/java.base/module-info.class");
    System.err.printf("%s %s\n", path, Files.size(path));
  }
}

Running on OpenJDK shows the program loading a file using the jrt filesystem:

$ javac JRTFS.java
$ jar cvfe j.jar JRTFS JRTFS.class
$ $JAVA11_HOME/bin/java -fullversion
openjdk full version "11.0.16+8"
$ java -jar j.jar $JAVA11_HOME
/modules/java.base/module-info.class 11056

Building with native-image:

$ wget https://download.oracle.com/graalvm/23/latest/graalvm-jdk-23_linux-x64_bin.tar.gz
$ tar xzvf graalvm-jdk-23_linux-x64_bin.tar.gz
$ ./graalvm-jdk-23.0.1+11.1/bin/native-image -H:ThrowMissingRegistrationErrors= --verbose --no-fallback -H:+AllowJRTFileSystem -jar j.jar
$ ./j $JAVA11_HOME
/modules/java.base/module-info.class 12508

If the GraalVM install is removed, the application fails, it appears to contain references to the GraalVM runtime that was used to create the native image.

$ rm -rf graalvm-jdk-23.0.1+11.1/
$ ./j $JAVA11_HOME
Exception in thread "main" java.nio.file.NoSuchFileException: /tmp/tmp.IWs9yCuUBd/graalvm-jdk-23.0.1+11.1/lib/modules
        at [email protected]/sun.nio.fs.UnixFileSystemProvider.newFileChannel(UnixFileSystemProvider.java:225)
        at [email protected]/java.nio.channels.FileChannel.open(FileChannel.java:309)
        at [email protected]/java.nio.channels.FileChannel.open(FileChannel.java:369)
        at [email protected]/jdk.internal.jimage.BasicImageReader.<init>(BasicImageReader.java:106)
        at [email protected]/jdk.internal.jimage.ImageReader$SharedImageReader.<init>(ImageReader.java:229)
        at [email protected]/jdk.internal.jimage.ImageReader$SharedImageReader.open(ImageReader.java:243)
        at [email protected]/jdk.internal.jimage.ImageReader.open(ImageReader.java:67)
        at [email protected]/jdk.internal.jimage.ImageReader.open(ImageReader.java:71)
        at [email protected]/jdk.internal.jrtfs.SystemImage.open(SystemImage.java:60)
        at [email protected]/jdk.internal.jrtfs.JrtFileSystem.<init>(JrtFileSystem.java:90)
        at [email protected]/jdk.internal.jrtfs.JrtFileSystemProvider.newFileSystem(JrtFileSystemProvider.java:109)
        at [email protected]/jdk.internal.jrtfs.JrtFileSystemProvider.newFileSystem(JrtFileSystemProvider.java:128)
        at [email protected]/jdk.internal.jrtfs.JrtFileSystemProvider.newFileSystem(JrtFileSystemProvider.java:107)
        at [email protected]/java.nio.file.FileSystems.newFileSystem(FileSystems.java:339)
        at [email protected]/java.nio.file.FileSystems.newFileSystem(FileSystems.java:288)
        at JRTFS.main(JRTFS.java:13)
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

I expected the native image to use the jrt filesystem to read from the provided java.home, instead of reading from the GraalVM that was used to create the native image.

Additional Context

No response

Run-Time Log Output and Error Messages

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions