GraalVM error: java.lang.NoClassDefFoundError: scala/Function0 (solution)

As a brief note to self, I was just trying to create a native image of a Scala application with GraalVM, and had this java.lang.NoClassDefFoundError error message:

[sbtmkdirs:16114]    classlist:   1,436.53 ms
Fatal error: java.lang.NoClassDefFoundError: scala/Function0
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.getDeclaredMethod(Class.java:2128)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:267)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:446)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:112)
Caused by: java.lang.ClassNotFoundException: scala.Function0
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 6 more
Error: Image build request failed with exit status 1

Solution

The short answer is that I didn’t have a SCALA_HOME environment variable set up when I tried to run the GraalVM native-image command. The solution was to set up my environment like this:

export SCALA_HOME=/Users/al/bin/scala-2.12.8
export JAVA_HOME=/Users/al/bin/graalvm-ce-19.1.1/Contents/Home
export PATH=/Users/al/bin/graalvm-ce-19.1.1/Contents/Home/bin:$PATH

Then I ran the GraalVM native-image command with a shell script with these contents:

JAR_FILE=sbtmkdirs_2.12-0.1.jar

echo "copying JAR file to current dir ..."
cp ../target/scala-2.12/${JAR_FILE} .

echo "running native-image ..."
# create a native image from the jar file and name
# the resulting executable `todo`
native-image -cp .:${SCALA_HOME}/lib/scala-library.jar:${JAR_FILE} --no-server -jar ${JAR_FILE} sbtmkdirs

Once I added the SCALA_HOME environment variable, everything worked as desired, resulting in this output:

running native-image ...
[sbtmkdirs:16129]    classlist:   4,885.10 ms
[sbtmkdirs:16129]        (cap):   3,956.83 ms
[sbtmkdirs:16129]        setup:   5,272.31 ms
[sbtmkdirs:16129]   (typeflow):   7,493.52 ms
[sbtmkdirs:16129]    (objects):   7,127.57 ms
[sbtmkdirs:16129]   (features):     337.21 ms
[sbtmkdirs:16129]     analysis:  15,255.59 ms
[sbtmkdirs:16129]     (clinit):   1,293.92 ms
[sbtmkdirs:16129]     universe:   1,593.46 ms
[sbtmkdirs:16129]      (parse):     636.69 ms
[sbtmkdirs:16129]     (inline):   1,499.38 ms
[sbtmkdirs:16129]    (compile):   7,536.83 ms
[sbtmkdirs:16129]      compile:  10,213.93 ms
[sbtmkdirs:16129]        image:   1,078.01 ms
[sbtmkdirs:16129]        write:     322.36 ms
[sbtmkdirs:16129]      [total]:  38,794.80 ms

If you get the java.lang.NoClassDefFoundError error message when trying to run native-image with GraalVM on a Scala application, I hope this solution is helpful.