プログラムで検出-JREのプレビューモード


8

Java 11以降、JavaコンパイラとランタイムのPREVIEW-MODEを有効にできます。新しい機能をプレビューすることができます。(JEP 12

java --enable-preview

プレビューモードを有効にしてJVMが起動されたかどうかをJava内から検出するにどうすればよいですか?

意図は、アプリケーション内ステータスページ/ jsonで実行中のコンテナーを説明することです-開発の概要。

これまでのところ、システムプロパティとフラグを調べましたが、どちらにもヒントが含まれていませんでした。


2
必要な機能を明示的に使用してコードを実行し、JVMが不平を言った場合は処理してください。
するThorbjörnRavnアンデルセン

2
ただ疑問に思っているのに、なぜそれをしたいのですか?このようなコードはフラグセットを使用してのみコンパイルするようにバインドされているため、コンパイルすらされないため、実行を忘れます。
ナマン

おそらくこの答えは、直接またはおそらく出発点として機能する可能性があります。自分でこれを行ったことはありませんが、あなたが尋ねていることと似ているようです。
kaan

2
@naman Java 11のほとんどのコードをコンパイルして、プレビューが保持するすべてのものをコンパイルすることができます。そのコードがtryブロック内に読み込まれている場合、失敗を処理できます。
するThorbjörnRavnアンデルセン

2
@kaanこれは、コードベンダーに依存するホットスポット機能を明示的に要求します。
するThorbjörnRavnアンデルセン

回答:


4

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));
    }

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.