Obtenir la version Java au moment de l'exécution

128

Je dois contourner un bogue Java dans JDK 1.5 qui a été corrigé dans 1.6. J'utilise la condition suivante:

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

Cela fonctionnera-t-il pour d'autres JVM? Y a-t-il une meilleure façon de vérifier cela?

liste
la source

Réponses:

41

Ces articles semblent suggérer que la vérification du préfixe 1.5ou du 1.6préfixe devrait fonctionner, car elle suit la convention de dénomination de version appropriée.

Articles techniques Sun

lubrifiants polygènes
la source
1
Existe-t-il un moyen d'obtenir que ce soit Oracle ou Open?
Joe C
89

java.versionest une propriété système qui existe dans chaque JVM. Il existe deux formats possibles pour cela:

  • Java 8 ou moins: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 ou supérieur: 9.0.1, 11.0.4, 12,12.0.1

Voici une astuce pour extraire la version majeure: S'il s'agit d'une 1.x.y_zchaîne de version, extrayez le caractère à l'index 2 de la chaîne. S'il s'agit d'une x.y.zchaîne de version, coupez la chaîne à son premier caractère de point, s'il en existe un.

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

Vous pouvez maintenant vérifier la version beaucoup plus confortablement:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
la source
7
C'est correct pour 1,5 mais 1,6 n'est pas précis en tant que nombre à virgule flottante.
Ha.
1
Mis à part la précision FP, pour les besoins de l'OP, le code fourni doit au moins être (version> 1.5), et non> =. Pour l'OP: si vous utilisez votre comparaison de chaînes actuelle, devez-vous également vérifier en dessous de 1,5?
Steven Mackenzie
1
@Ha: Peut-être mais double version = 1.6et Double.parseDouble("1.6")devrait toujours produire le même motif de bits, non? Puisque nous ne faisons pas d'arithmétique sur le nombre (seulement une simple comparaison), même == fonctionnera comme prévu.
Aaron Digulla
1
mais bientôt nous aurons à nouveau la version 1.1 ... ou peut-être qu'au lieu de 1.10 nous commençons avec 2.0 [:-)
user85421
7
Dans Java 9, il n'y aura pas de "1". devant. La chaîne commencera par "9 ..."
Dave C
59

Qu'en est-il d'obtenir la version à partir des méta-infos du package:

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

Imprime quelque chose comme:

1.7.0_13

Stefan
la source
9
Wow, ça m'a époustouflé. Bien que dans mon cas, tout ce que je voulais, c'était les deux premières parties de la version donc:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()semble revenir nullsur JDK9.
tresf le
Peut-être que cela ne fonctionne que lorsqu'il est défini dans MANIFEST.MF?
Aaron Digulla
30

Runtime.version()

Depuis Java 9, vous pouvez utiliser Runtime.version(), qui renvoie un Runtime.Version:

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

Le moyen le plus simple ( java.specification.version ):

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

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

ou quelque chose comme ( java.version ):

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

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

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

ou si vous voulez tout casser ( 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
la source
11

Juste une note que dans Java 9 et plus, la convention de dénomination est différente. System.getProperty("java.version")renvoie "9"plutôt que "1.9".

Sina Madani
la source
8

Ne fonctionne pas, besoin --posd'évaluer le double:

    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
la source
7

Exemple pour 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
la source
1
version < 1.4f... Que se passe-t-il quand version = 1.4f?
ADTC
Ah oui, vous avez raison - 1.4f ne serait pas capturé dans l'exemple ci-dessus. L'exemple ne montre que les constantes d'Apache Commons Lang comme alternative aux propriétés de Java :)
mvanle
Vous pouvez modifier la réponse et la changer en version <= 1.4f.. Malheureusement, SystemUtilsne fournit pas de isJavaVersionLessThanméthode mais alors (heureusement) vous pouvez également mettre le code hérité dans un elsebloc, ce qui est plus propre.
ADTC
Err ... "clause douteuse pour attraper 1.4" ? Ne devrait pas 1.4frevenir au code hérité?
ADTC
2
Je suggère: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Code spécifique ci-dessus, code générique ci-dessous, code de secours tout en bas.
ADTC
5

Voici l'implémentation dans 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
la source
4

Si vous pouvez avoir une dépendance aux utils apache, vous pouvez utiliser org.apache.commons.lang3.SystemUtils.

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

Voici la réponse de @mvanle, converti en 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
la source