Reputation: 2970
I have a little Java program. I build a binary using Graal's native-image
(i.e. GraalVM AOT aka SubstrateVM).
My program can be executed either with a Java runtime or from the native-image binary. What's the best way to tell which context I'm running in?
(This might be a bad practice in general but I believe it's inevitable/necessary in certain not-uncommon circumstances.)
Upvotes: 7
Views: 1562
Reputation: 151
You can use refelction to try to get a class which only exists in graalvm.
private boolean checkGraalVM() {
try {
Class.forName("org.graalvm.home.Version");
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
Upvotes: 0
Reputation: 1182
Edit: There is now an API for that. See user7983712's answer.
The way it's done in the GraalVM is by capturing the com.oracle.graalvm.isaot
system property: it is set to true
while building AOT images. If you combine that with the fact that static initializers run during image generation, you can use
static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot")
This boolean will remain true when running the native image.
This is also useful to cut-off paths that you don't want in the final output: for example if you have some code that uses a feature that SVM doesn't support (e.g., dynamic class-loading) you can predicate it with !IS_AOT
.
Upvotes: 5
Reputation: 56
GraalVM now provides an API for checking the AOT context:
ImageInfo.inImageCode()
ImageInfo.inImageRuntimeCode()
ImageInfo.inImageBuildtimeCode()
ImageInfo.isExecutable()
ImageInfo.isSharedLibrary()
Upvotes: 4
Reputation: 2970
I'm leaning towards checking the presence/absence of some system properties. When I print out the system properties under Graal AOT I see:
{os.arch=x86_64, file.encoding=UTF-8, user.home=/Users/thom, path.separator=:, os.name=Mac OS X, user.dir=/Users/thom, line.separator=
, sun.jnu.encoding=UTF-8, file.separator=/, java.io.tmpdir=/var/folders/0x/rms5rjn526x33rm394xwmr8c0000gn/T/, user.name=thom}
As you may notice it's fairly short and is missing all the usual java.*
ones such as java.class.path
. I'll omit listing the lengthy Java version and instead link to another SO listing the usual Java System properties:
What is the full list of standard keys recognized by the Java System.getProperty() method?
So one way to do it would seem to be to check whether one or more of the java.*
properties are absent.
AFAIK there are no plans to set these in SubstrateVM. But System properties are mutable so one could possibly choose to fake them.
But anyway here's a way to do it:
def isGraalAOT = System.properties.getProperty("java.class.path") == null
Upvotes: 0