Table of contents
TidBits
Create Graal Native Image
./gradlew nativeCompile
using the following to generate reflection meta-data
java -agentlib:native-image-agent=config-output-dir=./META-INF/native-image -jar your-micronaut-app.jar
Reflective Acccess
add a
reflect-config.json
for refelctive access
to
/src/main/resources/META-INF/native-image/[package]
Run Native Image In Dev
./build/native/nativeCompile/graal-mail -Dmicronaut.environments=dev
Reflective Access
add a
reflect-config.json
soGraal
recognizes imported classes that need to be reflective
touch /src/main/resources/META-INF/native-image/com/ssi/reflect-config.json
{
"name": "fts.marketing.utils.deserializers.CampaignEmailStatusDeserializer",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredClasses": true,
"allPublicClasses": true
}
GraalVM annotation processor
gradle import
annotationProcessor("io.micronaut:micronaut-graal")
This processor generates additional classes that implement the GraalReflectionConfigurer Interface and programmatically register reflection configuration.
Example Class:
@ReflectiveAccess
@Serdeable
public class Integration {
//code
}
TidBits
Bug with GraalVM and Java Records
include the flag when building the native executable
--report-unsupported-elements-at-runtime
Create the file
native-image.properties
at
src/main/resources/META-INF/native-image/example.micronaut/guide/native-image.properties
MY Example, only line in text file
Args = --report-unsupported-elements-at-runtime
Gradle
The Gradle plugin has a new
testNativeImage
task that builds theGraalVM
Native Image and uses the native application as an embedded
server enabling the ability to write native integration tests.
Method to check if GraalVM JDK Distribution
Method to check if you are running in GraalVM JDK distribution. I have used it often in Gradle build files to decide whether a Gradle task should be
enabled.
public class GraalStuff {
private static boolean isGraalVMJava() {
return (System.getProperty("java.home") != null && Files.exists(Paths.get("${System.getProperty("java.home")}/lib/graalvm")))
|| Arrays.asList("jvmci.Compiler", "java.vendor.version", "java.vendor")
.stream()
.anyMatch(propertyName -> {
String value = System.getProperty(propertyName);
return value != null && value.toLowerCase(Locale.ENGLISH)
.contains("graal");
});
}
}
add tool chain to gradle
You can already build a native executable by running ./gradlew nativeCompile
or run it directly by invoking ./gradlew nativeRun
However, at this stage, running the native executable will fail because
this application requires additional metadata: you need to provide it with a list of resources to load.
Instruct the plugin to automatically detect resources to be included in the native executable. Add this to your build.gradle
file:
graalvmNative {
binaries.all {
resources.autodetect()
}
toolchainDetection = false
}
Another thing to note here, the plugin may not be able to properly detect the GraalVM
installation because of limitations in Gradle.
By default, the plugin selects a Java 11 GraalVM Community Edition
If you want to use GraalVM Enterprise
, or a particular version of GraalVM
and Java
, you need to explicitly tell in plugin’s configuration.
For example:
graalvmNative {
binaries {
main(({
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
vendor = JvmVendorSpec.matching("GraalVM Community")
}
} as java.lang.String))
}
}
my working example
graalvmNative {
toolchainDetection = false
binaries {
main(({
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.matching("GraalVM Community")
}
imageName.set('graal-vm-ssi')
buildArgs.add('--verbose')
} as java.lang.String))
}
}
The workaround to this is to disable toolchain detection with this command
toolchainDetection = false
get java toolchains
./gradlew-q javaToolchains
output
Oracle JDK 11.0.18+9-LTS-jvmci-22.3-b11
| Location: /Library/Java/JavaVirtualMachines/graalvm-ee-java11-22.3.1/Contents/Home
| Language Version: 11
| Vendor: Oracle
| Architecture: x86_64
| Is JDK: true
| Detected by: Current JVM