您如何判断您的 Java 程序在 GraalVM AOT 上下文中是否为 运行?

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

我有一个小Java程序。我使用 Graal 的 native-image(即 GraalVM AOT aka SubstrateVM)构建了一个二进制文件。

我的程序可以使用 Java 运行时或从本机映像二进制文件执行。判断我 运行 处于哪种环境的最佳方式是什么?

(这在一般情况下可能是一种不好的做法,但我认为在某些并不少见的情况下 inevitable/necessary。)

我倾向于检查某些系统属性的 presence/absence。当我打印出 Graal AOT 下的系统属性时,我看到:

{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}

您可能会注意到它相当短,并且缺少所有常见的 java.*,例如 java.class.path。我将省略列出冗长的 Java 版本,而是 link 列出通常的 Java 系统属性的另一个 SO:

What is the full list of standard keys recognized by the Java System.getProperty() method?

因此,一种方法似乎是检查是否缺少一个或多个 java.* 属性。

据我所知,没有计划在 SubstrateVM 中设置这些。但是系统属性是可变的,因此可以选择伪造它们。

但无论如何这里有一个方法可以做到:

def isGraalAOT = System.properties.getProperty("java.class.path") == null

编辑:现在有一个 API。见 user7983712 的回答。

在 GraalVM 中完成的方式是捕获 com.oracle.graalvm.isaot 系统 属性:在构建 AOT 映像时将其设置为 true。如果在图像生成期间将其与静态初始值设定项 运行 相结合,则可以使用

static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot")

当 运行使用本机图像时,此布尔值将保持为真。

这对于在最终输出中切断您不想要的路径也很有用:例如,如果您有一些代码使用 SVM 不支持的功能(例如,动态 class-loading) 你可以用 !IS_AOT.

来预测它

GraalVM 现在提供 API 用于检查 AOT 上下文:

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