Получение версии Java во время выполнения

128

Мне нужно обойти ошибку Java в JDK 1.5, которая была исправлена ​​в версии 1.6. Я использую следующее условие:

if (System.getProperty("java.version").startsWith("1.5.")) {
    ...
} else {
    ...
}

Будет ли это работать для других JVM? Есть ли лучший способ это проверить?

список
источник

Ответы:

41

Эти статьи, кажется, предполагают, что проверка 1.5или 1.6префикса должна работать, поскольку она соответствует правильному соглашению об именах версий.

Технические статьи Sun

polygenelubricants
источник
1
Есть ли способ узнать, Oracle это или Open?
Joe C
90

java.version- это системное свойство, которое существует в каждой JVM. Для этого есть два возможных формата:

  • Java 8 или уменьшить: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 или выше: 9.0.1, 11.0.4, 12,12.0.1

Вот трюк для извлечения основной версии: если это 1.x.y_zстрока версии, извлеките символ в индексе 2 строки. Если это x.y.zстрока версии, обрежьте строку до первого символа точки, если таковой существует.

private static int getVersion() {
    String version = System.getProperty("java.version");
    if(version.startsWith("1.")) {
        version = version.substring(2, 3);
    } else {
        int dot = version.indexOf(".");
        if(dot != -1) { version = version.substring(0, dot); }
    } return Integer.parseInt(version);
}

Теперь проверить версию стало намного удобнее:

if(getVersion() < 6) {
    // ...
}
Аарон Дигулла
источник
7
Это нормально для 1.5, но 1.6 не является точным числом с плавающей запятой.
Ха.
1
Помимо точности FP, для нужд OP предоставленный код должен быть как минимум (версия> 1.5), а не> =. В OP: если вы используете текущее сравнение строк, вам также нужно проверить ниже 1,5?
Стивен Маккензи,
1
@Ha: Может быть , но double version = 1.6и Double.parseDouble("1.6")все равно должны дать тот же битовый шаблон, верно? Поскольку мы не выполняем арифметические операции с числами (только простое сравнение), даже == будет работать должным образом.
Аарон Дигулла
1
но скоро у нас снова будет версия 1.1 ... или, может быть, вместо 1.10 мы начнем с 2.0 [:-)
user85421 04
7
В Java 9 не будет «1». спереди. Строка будет начинаться с «9 ...»
Дэйв Си
59

Как насчет получения версии из метаинформации пакета:

String version = Runtime.class.getPackage().getImplementationVersion();

Распечатывает что-то вроде:

1.7.0_13

Стефан
источник
9
Ух ты, это взорвало мне голову. Хотя в моем случае все, что я хотел, это первые две части версии, так что:Runtime.class.getPackage().getSpecificationVersion()
Уэсли Хартфорд
8
Runtime.class.getPackage().getImplementationVersion()похоже, возвращается nullна JDK9.
tresf
Может быть, это работает только тогда, когда это определено в MANIFEST.MF?
Аарон Дигулла
32

Runtime.version()

Начиная с Java 9, вы можете использовать Runtime.version(), который возвращает Runtime.Version:

Runtime.Version version = Runtime.version();
Eng.Fouad
источник
echo "System.err.print (Runtime.version (). major ())" | $ JDK / bin / jshell 2> & 1> / dev / null
judovana
29

Самый простой способ ( java.specification.version ):

double version = Double.parseDouble(System.getProperty("java.specification.version"));

if (version == 1.5) {
    // 1.5 specific code
} else {
    // ...
}

или что-то вроде ( java.version ):

String[] javaVersionElements = System.getProperty("java.version").split("\\.");

int major = Integer.parseInt(javaVersionElements[1]);

if (major == 5) {
    // 1.5 specific code
} else {
    // ...
}

или если вы хотите все это разбить ( java.runtime.version ):

String discard, major, minor, update, build;

String[] javaVersionElements = System.getProperty("java.runtime.version").split("\\.|_|-b");

discard = javaVersionElements[0];
major   = javaVersionElements[1];
minor   = javaVersionElements[2];
update  = javaVersionElements[3];
build   = javaVersionElements[4];
mvanle
источник
11

Просто обратите внимание, что в Java 9 и выше соглашение об именах другое. System.getProperty("java.version")возвращается, "9"а не "1.9".

Сина Мадани
источник
8

Не работает, нужно --posоценивать дважды:

    String version = System.getProperty("java.version");
    System.out.println("version:" + version);
    int pos = 0, count = 0;
    for (; pos < version.length() && count < 2; pos++) {
        if (version.charAt(pos) == '.') {
            count++;
        }
    }

    --pos; //EVALUATE double

    double dversion = Double.parseDouble(version.substring(0, pos));
    System.out.println("dversion:" + dversion);
    return dversion;
}
Alessandro
источник
7

Пример для Apache Commons Lang:

import org.apache.commons.lang.SystemUtils;

    Float version = SystemUtils.JAVA_VERSION_FLOAT;

    if (version < 1.4f) { 
        // legacy
    } else if (SystemUtils.IS_JAVA_1_5) {
        // 1.5 specific code
    } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) {
        // 1.6 compatible code
    } else {
        // dodgy clause to catch 1.4 :)
    }
mvanle
источник
1
version < 1.4f... Что происходит когда version = 1.4f?
ADTC 04
Ах да, вы правы - 1.4f не будет захвачен в приведенном выше примере. Этот пример демонстрирует только константы Apache Commons Lang в качестве альтернативы свойствам Java :)
mvanle
Вы можете отредактировать ответ и изменить его на version <= 1.4f... К сожалению SystemUtils, не предоставляет isJavaVersionLessThanметод, но тогда (к счастью) вы также можете поместить устаревший код в elseблок, который будет чище.
ADTC 03
Эээ ... "хитрая статья, чтобы поймать 1.4" ? Не следует 1.4fвозвращаться к устаревшему коду?
ADTC
2
Я хотел бы предложить: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Конкретный код выше, общий код ниже, резервный код в самом низу.
ADTC
5

Вот реализация в JOSM :

/**
 * Returns the Java version as an int value.
 * @return the Java version as an int value (8, 9, etc.)
 * @since 12130
 */
public static int getJavaVersion() {
    String version = System.getProperty("java.version");
    if (version.startsWith("1.")) {
        version = version.substring(2);
    }
    // Allow these formats:
    // 1.8.0_72-ea
    // 9-ea
    // 9
    // 9.0.1
    int dotPos = version.indexOf('.');
    int dashPos = version.indexOf('-');
    return Integer.parseInt(version.substring(0,
            dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1));
}
simon04
источник
4

Если у вас может быть зависимость от утилит apache, вы можете использовать org.apache.commons.lang3.SystemUtils.

    System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
P.Kurek
источник
1

Вот ответ от @mvanle, преобразованного в Scala: scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b") javaVerPrefix: String = 1 javaVerMajor: String = 8 javaVerMinor: String = 0

Майк Слинн
источник