-
Notifications
You must be signed in to change notification settings - Fork 0
Compiling a native image with GraalVM, gradle graal, gradle and picocli
There are two gradle plugins to integrate GraalVM into gradle:
- gradle-graal by Palantir Technologies
- Gradle plugin for GraalVM Native Image building by the GraalVM team
Both offer similar functionality, in that they only support either java 8 or java 11 and require either Windows SDK 7.1 or Visual Studio 2017/2019 with the accompanying Windows SDK 10.x. To install the Windows SDK see this guide.
When using gradle-graal the following configuration is required:
-
Add the following code to the gradle.build file:
plugins { id 'java' id 'com.palantir.graal' version '0.12.0' }
compileJava { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 options.compilerArgs += ["-Aproject=${project.name}"] }
graal { mainClass 'org.jajaho.main.Main' outputName 'nacli' javaVersion '11' windowsVsVarsPath 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat' option '--no-fallback' }
-
For me the last line "option '--no-fallback'" had no effect, the code would compile to a fallback image with and without the option enabled, if necessary. What did have an effect is picoclis annotation processor, it is necessary because picocli uses the refelction API and in order for GraalVM to be able to compile reflections ahead of time a reflection config is necessary. The annotation processor can be enabled by adding the following code to the gradle.build file along side the picocli implementation:
dependencies { // https://mvnrepository.com/artifact/info.picocli/picocli implementation group: 'info.picocli', name: 'picocli', version: '4.6.3' //annotationProcessor 'info.picocli:picocli-codegen:4.6.3' }
- However, when using the annotation processor the graal compiler is able to make a native image without fallback which also executes. But certain commands that work when compiling with a SDK (e.g. with a fallback image) lead to a runtime error. See the error-log below:
org.jgrapht.util.SupplierException: org.jajaho.data.Edge.<init>() at org.jgrapht.util.SupplierUtil.lambda$getThrowingSupplier$4942be5b$1(SupplierUtil.java:94) at org.jgrapht.graph.AbstractBaseGraph.addEdge(AbstractBaseGraph.java:260) at org.jajaho.main.Main.parseEdge(Main.java:198) at org.jajaho.util.ReadUtil.read(ReadUtil.java:15) at org.jajaho.main.Main.mainInterface(Main.java:120) at org.jajaho.main.Main.call(Main.java:129) at org.jajaho.main.Main.call(Main.java:16) at picocli.CommandLine.executeUserObject(CommandLine.java:1953) at picocli.CommandLine.access$1300(CommandLine.java:145) at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358) at picocli.CommandLine$RunLast.handle(CommandLine.java:2352) at picocli.CommandLine$RunLast.handle(CommandLine.java:2314) at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179) at picocli.CommandLine$RunLast.execute(CommandLine.java:2316) at picocli.CommandLine.execute(CommandLine.java:2078) at org.jajaho.main.Main.main(Main.java:29) Caused by: java.lang.NoSuchMethodException: org.jajaho.data.Edge.<init>() at java.lang.Class.getConstructor0(DynamicHub.java:3349) at java.lang.Class.getDeclaredConstructor(DynamicHub.java:2553) at org.jgrapht.util.SupplierUtil.createSupplier(SupplierUtil.java:76) at org.jgrapht.graph.Pseudograph.<init>(Pseudograph.java:47) at org.jajaho.data.CircuitGraph.<init>(CircuitGraph.java:8) at org.jajaho.main.Main.mainInterface(Main.java:34) ... 11 more
- More information on compability with native image, see: Native Image Compatibility and Optimization Guide
- A good (but lacking) quick-start guide, see: Building native Java CLIs with GraalVM, Picocli, and Gradle by Mich Seymour