Obtener la versión de Java en tiempo de ejecución

128

Necesito evitar un error de Java en JDK 1.5 que se corrigió en 1.6. Estoy usando la siguiente condición:

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

¿Funcionará para otras JVM? ¿Hay una mejor manera de verificar esto?

lista
fuente

Respuestas:

41

Estos artículos parecen sugerir que la comprobación 1.5o el 1.6prefijo deberían funcionar, ya que sigue la convención de nomenclatura de la versión adecuada.

Artículos técnicos de Sun

poligenelubricantes
fuente
1
¿Hay alguna forma de obtener si es Oracle o Open?
Joe C
89

java.versiones una propiedad del sistema que existe en cada JVM. Hay dos formatos posibles para ello:

  • Java 8 o bajar: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 o superior: 9.0.1, 11.0.4, 12,12.0.1

Aquí hay un truco para extraer la versión principal: si es una 1.x.y_zcadena de versión, extraiga el carácter en el índice 2 de la cadena. Si es una x.y.zcadena de versión, corte la cadena a su primer carácter de punto, si existe.

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

Ahora puedes comprobar la versión mucho más cómodamente:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
fuente
77
Está bien para 1.5 pero 1.6 no es preciso como un número de coma flotante.
Ja.
1
Dejando a un lado la precisión de FP, para las necesidades del OP, el código proporcionado debe ser al menos (versión> 1.5), no> =. Para el OP: si usa su comparación de cadenas actual, ¿también necesita verificar debajo de 1.5?
Steven Mackenzie
1
@Ha: Tal vez, pero double version = 1.6, y Double.parseDouble("1.6")aún deben producir el mismo patrón de bits, ¿verdad? Como no hacemos aritmética en el número (solo una comparación simple), incluso == funcionará como se esperaba.
Aaron Digulla
1
pero pronto tendremos la versión 1.1 nuevamente ... o tal vez en lugar de 1.10 comenzamos con 2.0 [:-)
user85421
77
En Java 9, no habrá "1". Al frente. La cadena comenzará con "9 ..."
Dave C
59

¿Qué hay de obtener la versión del paquete de metainformaciones:

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

Imprime algo como:

1.7.0_13

Stefan
fuente
9
Wow, eso me dejó boquiabierto. Aunque en mi caso, todo lo que quería eran las dos primeras partes de la versión, así que:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()parece regresar nullen JDK9.
tresf
¿Quizás esto solo funciona cuando se define en MANIFEST.MF?
Aaron Digulla
30

Runtime.version()

Desde Java 9, puede usar Runtime.version(), que devuelve un Runtime.Version:

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

La forma más simple ( java.specification.version ):

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

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

o algo así como ( java.version ):

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

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

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

o si quieres dividirlo todo ( 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
fuente
11

Solo una nota de que en Java 9 y superior, la convención de nomenclatura es diferente. System.getProperty("java.version")devuelve en "9"lugar de "1.9".

Sina Madani
fuente
8

No funciona, necesita --posevaluar doble:

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

Ejemplo para 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
fuente
1
version < 1.4f... ¿Qué pasa cuando version = 1.4f?
ADTC
Ah, sí, tienes razón: 1.4f no se capturaría en el ejemplo anterior. El ejemplo solo demuestra las constantes de Apache Commons Lang como una alternativa a las propiedades de Java :)
mvanle
Puede editar la respuesta y cambiarla a version <= 1.4f... Desafortunadamente SystemUtilsno proporciona un isJavaVersionLessThanmétodo, pero luego (afortunadamente) también podría poner el código heredado en un elsebloque, que es más limpio.
ADTC
Err ... "cláusula dudosa para atrapar 1.4" ? ¿No debería 1.4frecurrir al código heredado?
ADTC
2
Yo sugeriría: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Código específico arriba, código genérico abajo, código alternativo en la parte inferior.
ADTC
5

Aquí está la implementación en 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
fuente
4

Si puede depender de las utilidades de apache, puede usar org.apache.commons.lang3.SystemUtils.

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

Aquí está la respuesta de @mvanle, convertida a 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
fuente