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

GraalVM support for native images #103

Open
klopfdreh opened this issue Oct 21, 2024 · 2 comments
Open

GraalVM support for native images #103

klopfdreh opened this issue Oct 21, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@klopfdreh
Copy link

klopfdreh commented Oct 21, 2024

Description

Because we want to use jgit in GraalVM native images it would be great if this could be achieved through this ticket.

Motivation

jgit in GraalVM native images.

Alternatives considered

N/A

Additional context

N/A

Spring Boot Workaround

@Configuration
@ImportRuntimeHints(GitHubRuntimeHints.class)
@Slf4j
public class GitHubRuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        Arrays.stream(System.getProperty("java.class.path").split(File.pathSeparator)).forEach(classpathEntry -> {
            // If the classpathEntry is no jar skip it
            if (!classpathEntry.endsWith(".jar")) {
                return;
            }

            try (JarInputStream is = new JarInputStream(Files.newInputStream(Path.of(classpathEntry)))) {
                JarEntry entry = is.getNextJarEntry();
                while (entry != null) {
                    String entryName = entry.getName();
                    if (entryName.endsWith(".class") && entryName.startsWith("org/eclipse/jgit") && !entryName.contains("package-info")) {
                        String githubApiClassName = entryName.replace("/", ".");
                        String githubApiClassNameWithoutClass = githubApiClassName.substring(0, githubApiClassName.length() - 6);
                        log.info("Registered class {} for reflections and serialization.", githubApiClassNameWithoutClass);
                        hints.reflection().registerType(TypeReference.of(githubApiClassNameWithoutClass), MemberCategory.values());
                        hints.serialization().registerType(TypeReference.of(githubApiClassNameWithoutClass));
                    }
                    entry = is.getNextJarEntry();
                }
            } catch (IOException e) {
                log.warn("Error while reading jars", e);
            }
        });

        hints.reflection()
            .registerType(TypeReference.of(IOException.class),
                hint -> hint.withMembers(MemberCategory.values())
            );

        hints.resources()
            .registerPattern("application.yml");
    }
}

Before the native-image command is used you have to set the environment varialbes

# Git configuration home folder
ENV XDG_CONFIG_HOME=/writablePath/
# Don't read git system configuration
ENV GIT_CONFIG_NOSYSTEM=true

Important: this is not a good solution as it enables all jgit classes for reflections and serialization.

An example of a native build can be found here: https://github.com/klopfdreh/native-cloud-config-test/blob/main/client/Dockerfile (Note: This does not use builder-image with multi stage and is only an example)

@msohn
Copy link
Member

msohn commented Nov 10, 2024

I don't understand what you think in JGit is wrong or missing in order to allow using it in GraalVM native images.

@klopfdreh
Copy link
Author

klopfdreh commented Nov 10, 2024

So there are some classes which are accessed via reflections and / or serialized. Also if static resources files are used from classpath they also need to be included ( example: JodaOrg/joda-time#784 ) If you don’t provide those hints it causes issues during runtime when using native-images with GraalVM. From what I tested IOException was used via reflections.

There is nothing wrong with JGit, but it requires some meta information files so that there are no issues with native-image. 😀

I created this ticket to check if reflection / serialization / static resources are used and to add those hints.

With my workaround mentioned in the description JGit is working without any issues in native images. 👍

For more information have a look at the GraalVM documentation: https://www.graalvm.org/latest/reference-manual/native-image/metadata/

Note: You can provide separate file for reflection / serialization / resources - the Spring Boot team documented it with my request: spring-projects/spring-boot#42515

@msohn msohn added the enhancement New feature or request label Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants