Lập trình phát hiện - Chế độ xem trước trong JRE


8

Kể từ Java 11, có thể bật tính năng TRƯỚC-MODE trên Trình biên dịch Java và Thời gian chạy. Nó cho phép xem trước các tính năng mới. ( JEP 12 )

java --enable-preview

Làm cách nào tôi có thể phát hiện từ bên trong Java xem JVM đã được khởi động khi bật chế độ xem trước chưa?

Mục đích là để mô tả container đang chạy trên trang trạng thái trong ứng dụng / json - để biết tổng quan về devops.

Cho đến nay tôi đã xem xét các thuộc tính hệ thống và cờ, không chứa một gợi ý nào.


2
Hãy thử chạy mã rõ ràng bằng cách sử dụng tính năng bạn cần và xử lý nếu JVM phàn nàn.
Thorbjørn Ravn Andersen

2
Chỉ cần tự hỏi, tại sao bạn muốn làm điều đó? Vì một mã như vậy bị ràng buộc chỉ biên dịch với bộ cờ nếu không nó thậm chí sẽ không biên dịch, quên thực thi.
Naman

có lẽ câu trả lời này có thể hoạt động, trực tiếp hoặc có thể là điểm khởi đầu. Tôi đã không làm điều này bản thân mình, nhưng nó dường như tương tự như những gì bạn đang hỏi về.
kaan

2
@naman bạn có thể biên dịch hầu hết mã cho java 11 và sau đó phần còn lại được biên dịch cho bất kỳ bản xem trước nào. Nếu mã đó được tải bên trong khối thử, bạn có thể xử lý lỗi.
Thorbjørn Ravn Andersen

2
@kaan điều này rõ ràng yêu cầu một tính năng hotspot làm cho nhà cung cấp mã phụ thuộc.
Thorbjørn Ravn Andersen

Câu trả lời:


4

Bạn có thể kiểm tra tệp Java Class_version. Nếu 0xFFFFtệp lớp được biên dịch với --enable-preview. Để biết chi tiết, xem https://stackoverflow.com/a/58821511/868941 .

Một chương trình đơn giản để kiểm tra điều này được đưa ra dưới đây (hãy cẩn thận, mã Java 13 với các tính năng xem trước được bật!).

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

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.