Ensure Compatibility with Graal

Issue #411 resolved
Marcus Böhm created an issue

Hey there,

first of all i would like to thank for developing this software! I am a backend engineer at Prisma. I am opening this issue as we are a happy user of this library and would like it to be compatible with Graal.

What is Graal?

Graal is a collection of tools. For one it is a JVM replacement that does not only run Java Bytecode but also other languages like Javascript or Ruby. It also comes with a tool called native image. This allows to compile a JAR into a standalone binary.

We would like to turn our Prisma Server into a lightweight binary with Graal.

However the Graal native image tool comes with some limitations. Some features of the JVM are not supported, e.g. the support for reflection is limited because it is not a good fit with ahead of time compilation. Therefore we created a test suite to check the compatibility of our used dependencies with Graal. For each dependency we tried to come up with a super small program and see whether it compiles with Graal or not.

The program to test compatibility with SnakeYAML can be found here.

What's the problem we have hit?

Exception in thread "main" java.lang.NullPointerException
    at org.yaml.snakeyaml.util.PlatformFeatureDetector.isRunningOnAndroid(PlatformFeatureDetector.java:25)
    at org.yaml.snakeyaml.introspector.PropertyUtils.<init>(PropertyUtils.java:60)
    at org.yaml.snakeyaml.introspector.PropertyUtils.<init>(PropertyUtils.java:50)
    at org.yaml.snakeyaml.constructor.BaseConstructor.getPropertyUtils(BaseConstructor.java:531)
    at org.yaml.snakeyaml.constructor.BaseConstructor.addTypeDescription(BaseConstructor.java:552)
    at org.yaml.snakeyaml.constructor.Constructor.<init>(Constructor.java:84)
    at org.yaml.snakeyaml.constructor.Constructor.<init>(Constructor.java:70)
    at org.yaml.snakeyaml.constructor.Constructor.<init>(Constructor.java:56)
    at org.yaml.snakeyaml.constructor.Constructor.<init>(Constructor.java:46)
    at org.yaml.snakeyaml.Yaml.<init>(Yaml.java:64)
    at Main$.main(Main.scala:9)
    at Main.main(Main.scala)
    at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:177)

I think the problem is the call to System.getProperty("java.runtime.name") that returns null within the native Graal runtime.

Note: The Graal compilation terminates on the first encountered error. Therefore there might be more problems that need to be addressed.

How can incompatibilities with Graal be fixed?

Here is a blog post by the Graal team that explains how the native image tool is working and how they were able to compile a server built on top of netty into a binary.

Comments (5)

  1. Andrey Somov

    What kind of support you expect from the SnakeYAML library ?

    It looks like the call to System.getProperty("java.runtime.name") should be fixed in Graal.

  2. Marcus Böhm reporter

    This issue in the Graal repo suggests that they can't fix that. I think the code should be written in a way that it does not assume this call will return something. In this specific case i would return false as the program is not running on Android then.

  3. Alexander Maslov

    I think you are correct. Only the "claim" in comment stops me from fixing it without hesitation

        public boolean isRunningOnAndroid() {
            if (isRunningOnAndroid == null) {
                // No risk of NPE because this property should always be available
                isRunningOnAndroid = System.getProperty("java.runtime.name").startsWith("Android Runtime");
            }
            return isRunningOnAndroid;
        }
    

    Unfortunately I can't find any grounds for that "claim" :) I will try figure out why that comment appeared there before fixing this.

  4. Log in to comment