Java-Version zur Laufzeit abrufen

128

Ich muss einen Java-Fehler in JDK 1.5 umgehen, der in 1.6 behoben wurde. Ich verwende die folgende Bedingung:

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

Funktioniert dies für andere JVMs? Gibt es eine bessere Möglichkeit, dies zu überprüfen?

aufführen
quelle

Antworten:

41

Diese Artikel scheinen darauf hinzudeuten, dass das Suchen nach 1.5oder das 1.6Präfix funktionieren sollte, da es der richtigen Namenskonvention für Versionen folgt.

Sun Technische Artikel

Polygenschmierstoffe
quelle
1
Gibt es eine Möglichkeit zu ermitteln, ob es sich um Oracle oder Open handelt?
Joe C
89

java.versionist eine Systemeigenschaft , die in jeder JVM vorhanden ist. Es gibt zwei mögliche Formate dafür:

  • Java 8 oder senken: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 oder höher: 9.0.1, 11.0.4, 12,12.0.1

Hier ist ein Trick, um die Hauptversion zu extrahieren: Wenn es sich um eine 1.x.y_zVersionszeichenfolge handelt, extrahieren Sie das Zeichen an Index 2 der Zeichenfolge. Wenn es sich um eine x.y.zVersionszeichenfolge handelt, schneiden Sie die Zeichenfolge auf das erste Punktzeichen, falls vorhanden.

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

Jetzt können Sie die Version viel bequemer überprüfen:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
quelle
7
Es ist in Ordnung für 1,5, aber 1,6 ist als Gleitkommazahl nicht genau.
Ha.
1
Abgesehen von der FP-Genauigkeit sollte der bereitgestellte Code für die Anforderungen des OP mindestens (Version> 1.5) und nicht> = sein. Zum OP: Wenn Sie Ihren aktuellen String-Vergleich verwenden, müssen Sie auch unter 1,5 prüfen?
Steven Mackenzie
1
@ Ha: Vielleicht aber double version = 1.6und Double.parseDouble("1.6")sollte trotzdem das gleiche Bitmuster ergeben, oder? Da wir keine Arithmetik für die Zahl durchführen (nur ein einfacher Vergleich), funktioniert sogar == wie erwartet.
Aaron Digulla
1
aber bald werden wir wieder Version 1.1 haben ... oder vielleicht beginnen wir statt 1.10 mit 2.0 [:-)
user85421
7
In Java 9 gibt es keine "1". vor. Die Saite beginnt mit "9 ..."
Dave C
59

Was ist mit dem Abrufen der Version aus den Paket-Meta-Infos:

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

Druckt etwas aus wie:

1.7.0_13

Stefan
quelle
9
Wow, diese Art hat mich umgehauen. In meinem Fall wollte ich nur die ersten beiden Teile der Version, also:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()scheint nullauf JDK9 zurückzukehren.
Tresf
Vielleicht funktioniert das nur, wenn es in MANIFEST.MF definiert ist?
Aaron Digulla
30

Runtime.version()

Seit Java 9 können Sie Folgendes verwenden : Runtime.version()a Runtime.Version:

Runtime.Version version = Runtime.version();
Eng.Fouad
quelle
echo "System.err.print (Runtime.version (). major ())" | $ JDK / bin / jshell 2> & 1> / dev / null
Judovana
29

Der einfachste Weg ( java.specification.version ):

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

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

oder so ähnlich wie ( java.version ):

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

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

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

oder wenn Sie alles aufteilen möchten ( 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
quelle
11

Nur ein Hinweis, dass in Java 9 und höher die Namenskonvention anders ist. System.getProperty("java.version")kehrt "9"eher zurück als "1.9".

Sina Madani
quelle
8

Funktioniert nicht, muss --posdoppelt bewertet werden:

    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
quelle
7

Beispiel für 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
quelle
1
version < 1.4f... was passiert wann version = 1.4f?
ADTC
Ah ja, Sie haben Recht - 1.4f würde im obigen Beispiel nicht erfasst. Das Beispiel zeigt nur die Konstanten von Apache Commons Lang als Alternative zu Javas Eigenschaften :)
mvanle
Sie können die Antwort bearbeiten und in ändern version <= 1.4f. Leider SystemUtilsgibt es keine isJavaVersionLessThanMethode, aber dann können Sie (zum Glück) auch den Legacy-Code in einen elsesaubereren Block einfügen .
ADTC
Äh ... "zwielichtige Klausel, um 1.4 zu fangen" ? Sollte man nicht 1.4fauf alten Code zurückgreifen?
ADTC
2
Ich würde vorschlagen : if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Spezifischer Code oben, generischer Code unten, Fallback-Code ganz unten.
ADTC
5

Hier ist die Implementierung in 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
quelle
3

Wenn Sie von Apache-Utils abhängig sein können, können Sie org.apache.commons.lang3.SystemUtils verwenden.

    System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
P.Kurek
quelle
1

Hier ist die Antwort von @mvanle, konvertiert zu 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
quelle