Pobieranie wersji Java w czasie wykonywania

128

Muszę obejść błąd Javy w JDK 1.5, który został naprawiony w wersji 1.6. Używam następującego warunku:

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

Czy to zadziała w przypadku innych maszyn JVM? Czy jest lepszy sposób, aby to sprawdzić?

lista
źródło

Odpowiedzi:

41

Te artykuły wydają się sugerować, że sprawdzanie prefiksu 1.5lub 1.6prefiksu powinno działać, ponieważ jest zgodne z konwencją nazewnictwa poprawnej wersji.

Artykuły techniczne firmy Sun

smary wielogenowe
źródło
1
Czy istnieje sposób, aby dowiedzieć się, czy jest to Oracle czy Open?
Joe C
89

java.versionto właściwość systemowa, która istnieje w każdej maszynie JVM. Istnieją dwa możliwe formaty:

  • Java 8 lub dolna: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 lub nowszy: 9.0.1, 11.0.4, 12,12.0.1

Oto sztuczka, aby wyodrębnić wersję główną: Jeśli jest to 1.x.y_zciąg wersji, wyodrębnij znak pod indeksem 2 ciągu. Jeśli jest to x.y.zciąg wersji, przytnij ciąg do pierwszego znaku kropki, jeśli taki istnieje.

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

Teraz możesz sprawdzić wersję o wiele wygodniej:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
źródło
7
Jest ok dla 1.5, ale 1.6 nie jest dokładną liczbą zmiennoprzecinkową.
Ha.
1
Pomijając precyzję PR, dla potrzeb PO podany kod powinien wynosić co najmniej (wersja> 1.5), a nie> =. Do OP: jeśli korzystasz z obecnego porównania ciągów, musisz również sprawdzić poniżej 1,5?
Steven Mackenzie
1
@Ha: Może, ale double version = 1.6i Double.parseDouble("1.6")nadal powinien dawać ten sam wzór bitowy, prawda? Ponieważ nie wykonujemy arytmetyki na liczbie (tylko proste porównanie), funkcja even == będzie działać zgodnie z oczekiwaniami.
Aaron Digulla,
1
ale wkrótce znowu będziemy mieć wersję 1.1 ... a może zamiast 1.10 zaczniemy od 2.0 [:-)
user85421
7
W Javie 9 nie będzie „1”. z przodu. Ciąg znaków rozpocznie się od „9…”
Dave C
59

A co z pobieraniem wersji z meta informacji o pakiecie:

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

Wyświetla coś takiego:

1.7.0_13

Stefan
źródło
9
Wow, to mnie rozwaliło. Chociaż w moim przypadku chciałem tylko dwóch pierwszych części wersji, więc:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()wydaje się wracać nullna JDK9.
tresf
Może to działa tylko wtedy, gdy jest zdefiniowane w MANIFEST.MF?
Aaron Digulla,
30

Runtime.version()

Od wersji Java 9 możesz użyć Runtime.version(), która zwraca Runtime.Version:

Runtime.Version version = Runtime.version();
Eng.Fouad
źródło
echo "System.err.print (Runtime.version (). major ())" | $ JDK / bin / jshell 2> & 1> / dev / null
judovana
29

Najprostszy sposób ( java.specification.version ):

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

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

lub coś takiego ( java.version ):

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

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

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

lub jeśli chcesz to wszystko zepsuć ( 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
źródło
11

Tylko uwaga, że ​​w Javie 9 i nowszych konwencja nazewnictwa jest inna. System.getProperty("java.version")zwraca "9"raczej niż "1.9".

Sina Madani
źródło
8

Nie działa, trzeba --posocenić podwójnie:

    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
źródło
7

Przykład dla 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
źródło
1
version < 1.4f... Co się stanie, kiedy version = 1.4f?
ADTC,
Ach tak, masz rację - 1,4f nie zostałby ujęty w powyższym przykładzie. Przykład pokazuje tylko stałe Apache Commons Langa jako alternatywę dla właściwości Javy :)
mvanle
Możesz edytować odpowiedź i zmienić ją na version <= 1.4f.. Niestety SystemUtilsnie podaje isJavaVersionLessThanmetody, ale potem (na szczęście) możesz również umieścić starszy kod w elsebloku, który jest bardziej przejrzysty.
ADTC
Err ... "podejrzana klauzula, aby złapać 1,4" ? Nie powinieneś 1.4fwrócić do starszego kodu?
ADTC
2
Proponuję: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Konkretny kod powyżej, kod ogólny poniżej, kod awaryjny na samym dole.
ADTC
5

Oto implementacja w 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
źródło
4

Jeśli możesz mieć zależność od narzędzi Apache, możesz użyć org.apache.commons.lang3.SystemUtils.

    System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
P.Kurek
źródło
1

Oto odpowiedź z @mvanle, przekonwertowana na Scala: scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b") javaVerPrefix: String = 1 javaVerMajor: String = 8 javaVerMinor: String = 0

Mike Slinn
źródło