java - 以编程方式检测 JRE 中的 --preview 模式

标签 java jvm-arguments java-13

从 Java 11 开始,可以启用 Java 编译器和运行时上的预览模式。它允许预览新功能。 ( JEP 12 )

java --enable-preview

我如何检测 来自 Java JVM 是否已经启动并启用了预览模式?

目的是在应用程序状态页面/json 上描述正在运行的容器 - 用于 devops 概述。

到目前为止,我研究了系统属性和标志,都没有包含任何提示。

最佳答案

您可以检查 Java 类文件 minor_version。如 0xFFFF类文件是用 --enable-preview 编译的。详情见https://stackoverflow.com/a/58821511/868941 .

下面给出了一个简单的程序来检查这一点(请注意,启用了预览功能的 Java 13 代码!)。

public final class ClassFileVersion {

    private final int major;
    private final int minor;

    private ClassFileVersion(int major, int minor) {
        this.major = major;
        this.minor = minor;
    }

    public static ClassFileVersion of(Class<?> classFile) throws IOException {
        try (InputStream is = classFile.getResourceAsStream("/%s.class".formatted(classFile.getName().replace('.', '/')))) {
            var buffer = new byte[8];
            if (is.read(buffer) != buffer.length) {
                throw new AssertionError("Not a Java Class File!");
            }
            return new ClassFileVersion(readUnsignedShort(buffer, 6), readUnsignedShort(buffer, 4));
        }
    }

    public String getVersionNumber() {
        return "%d.%d".formatted(major, minor);
    }

    public boolean isEnablePreview() {
        return major >= 55 && minor == 0xFFFF;
    }

    @Override
    public String toString() {
        return (major < 49 ? "JDK " : "Java SE ") +
            switch(major) {
                case 45 -> "1.1";
                case 46 -> "1.2";
                case 47 -> "1.3";
                case 48 -> "1.4";
                case 49 -> "5";
                case 50 -> "6";
                case 51 -> "7";
                case 52 -> "8";
                case 53 -> "9";
                case 54 -> "10";
                case 55 -> "11";
                case 56 -> "12";
                case 57 -> "13";
                case 58 -> "14";
                default -> throw wrongVersion();
            } +
            switch(minor) {
                case 0 -> "";
                case 3 -> {
                    if (major != 45) {
                        throw wrongVersion();
                    }
                    yield "";
                }
                case 0xFFFF -> " --enable-preview";
                default -> throw wrongVersion();
            };
    }

    private static int readUnsignedShort(byte[] buffer, int offset) {
        return ((buffer[offset] & 0xff) << 8) + (buffer[++offset] & 0xff);
    }

    private AssertionError wrongVersion() {
        return new AssertionError("Wrong Java Class File Version: %d.%d".formatted(major, minor));
    }
    // to run this code (JDK 13 needed):
    // java --enable-preview --source 13 ClassFileVersion.java 
    public static void main(String[] args) throws IOException {
        // prints "Java SE 13 --enable-preview"
        System.out.println(ClassFileVersion.of(ClassFileVersion.class));
    }

}

关于java - 以编程方式检测 JRE 中的 --preview 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58327000/

相关文章:

java - 如何使用枚举?

java - 带数组的迭代器循环

java - 如何使用 Gradle 设置 JPMS 模块的 ModuleMainClass 属性?

java - Intellij Idea NoClassDefFoundError : com/intellij/util/messages/Topic

java - 使用 selenium 无法访问 org.openqa.selenium.webdriver 错误?

java - 世博会弹出的应用程序因 java.net.ConnectException 崩溃

java - jsp:UseBean 与 Struts <bean> 标签

tomcat9 - Tomcat 服务未使用弹性 APM java 代理启动

使用 client-auth 的 Java 客户端在代码中工作,但不使用 vm-arguments

java - JVM ARGS '-Xms1024m -Xmx2048m' 在 Java 8 中仍然有用吗?