tksfz
tksfz

Reputation: 2970

How can you tell if your Java program is running in a GraalVM AOT context?

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

Answers (4)

Li Yu Heng
Li Yu Heng

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

Gilles D.
Gilles D.

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

codrut.stancu
codrut.stancu

Reputation: 56

GraalVM now provides an API for checking the AOT context:

ImageInfo.inImageCode()
ImageInfo.inImageRuntimeCode()
ImageInfo.inImageBuildtimeCode()
ImageInfo.isExecutable()
ImageInfo.isSharedLibrary()

Upvotes: 4

tksfz
tksfz

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

Related Questions