我有一个小的 Java 程序。我使用 Graal native-image
(即 GraalVM AOT aka SubstrateVM)构建了一个二进制文件。
我的程序可以使用 Java 运行时或从本机映像二进制文件执行。判断我在哪个上下文中运行的最佳方法是什么?
(总的来说,这可能是一种不好的做法,但我相信在某些不常见的情况下这是不可避免的/必要的。)
我有一个小的 Java 程序。我使用 Graal native-image
(即 GraalVM AOT aka SubstrateVM)构建了一个二进制文件。
我的程序可以使用 Java 运行时或从本机映像二进制文件执行。判断我在哪个上下文中运行的最佳方法是什么?
(总的来说,这可能是一种不好的做法,但我相信在某些不常见的情况下这是不可避免的/必要的。)
GraalVM 现在提供了一个用于检查 AOT 上下文的API :
ImageInfo.inImageCode()
ImageInfo.inImageRuntimeCode()
ImageInfo.inImageBuildtimeCode()
ImageInfo.isExecutable()
ImageInfo.isSharedLibrary()
编辑:现在有一个 API。请参阅 user7983712 的答案。
在 GraalVM 中完成的方式是通过捕获系统属性:在构建 AOT 图像时com.oracle.graalvm.isaot
将其设置为。true
如果您将其与静态初始化程序在图像生成期间运行的事实结合起来,您可以使用
static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot")
运行本机映像时,此布尔值将保持为真。
这对于在最终输出中截断您不想要的路径也很有用:例如,如果您有一些代码使用了 SVM 不支持的功能(例如,动态类加载),您可以使用!IS_AOT
.
我倾向于检查某些系统属性的存在/不存在。当我在 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 版本,而是链接到另一个列出常用 Java 系统属性的 SO:
Java System.getProperty() 方法识别的标准键的完整列表是什么?
因此,一种方法似乎是检查一个或多个java.*
属性是否不存在。
AFAIK 没有计划在 SubstrateVM 中设置这些。但是系统属性是可变的,因此人们可能会选择伪造它们。
但无论如何,这是一种方法:
def isGraalAOT = System.properties.getProperty("java.class.path") == null