Obtendo a versão Java em tempo de execução

128

Preciso solucionar um bug do Java no JDK 1.5 que foi corrigido na 1.6. Estou usando a seguinte condição:

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

Isso funcionará para outras JVMs? Existe uma maneira melhor de verificar isso?

Lista
fonte

Respostas:

41

Esses artigos parecem sugerir que a verificação 1.5ou o 1.6prefixo funcione, conforme segue a convenção de nomenclatura de versão adequada.

Artigos técnicos da Sun

poligenelubricants
fonte
1
Existe uma maneira de obter se é Oracle ou Open?
Joe C
89

java.versioné uma propriedade do sistema que existe em todas as JVM. Existem dois formatos possíveis para isso:

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

Aqui está um truque para extrair a versão principal: Se for uma 1.x.y_zstring de versão, extraia o caractere no índice 2 da string. Se for uma x.y.zsequência de versões, corte a sequência no primeiro caractere de ponto, se houver.

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

Agora você pode verificar a versão com muito mais conforto:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
fonte
7
É bom para 1,5, mas 1,6 não é preciso como número de ponto flutuante.
Ha.
1
Além da precisão do FP, para as necessidades do OP, o código fornecido deve ser pelo menos (versão> 1.5), não> =. Para o OP: se você usa sua comparação atual de String, também precisa verificar abaixo de 1,5?
9788 Steven Spielberg #
1
@Ha: Talvez, mas double version = 1.6e Double.parseDouble("1.6")ainda deve produzir o mesmo padrão pouco, certo? Como não fazemos aritmética no número (apenas uma comparação simples), mesmo == funcionará conforme o esperado.
Aaron Digulla
1
mas em breve teremos a versão 1.1 de novo ... ou talvez em vez de 1,10 começamos com 2,0 [:-)
user85421
7
No Java 9, não haverá "1". em frente. A cadeia de caracteres começará com "9 ..."
Dave C
59

Que tal obter a versão das meta informações do pacote:

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

Imprime algo como:

1.7.0_13

Stefan
fonte
9
Uau, isso meio que me deixou louco. Embora no meu caso, tudo o que eu queria era as duas primeiras partes da versão da seguinte forma:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()parece retornar nullno JDK9.
tresf
Talvez isso só funcione quando definido no MANIFEST.MF?
Aaron Digulla
30

Runtime.version()

Desde o Java 9, você pode usar Runtime.version(), que retorna um Runtime.Version:

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

A maneira mais simples ( java.specification.version ):

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

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

ou algo como ( java.version ):

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

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

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

ou se você quiser dividir tudo ( 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
fonte
11

Apenas observe que no Java 9 e acima, a convenção de nomenclatura é diferente. System.getProperty("java.version")retorna em "9"vez de "1.9".

Sina Madani
fonte
8

Não funciona, precisa --posavaliar o dobro:

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

Exemplo para o 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
fonte
1
version < 1.4f... O que acontece quando version = 1.4f?
ADTC
Ah, sim, você está certo - 1.4f não seria capturado no exemplo acima. O exemplo é apenas demonstrando constantes do Apache Commons Lang como uma alternativa para as propriedades de Java :)
mvanle
Você pode editar a resposta e alterá-la para version <= 1.4f.. Infelizmente SystemUtils, não fornece um isJavaVersionLessThanmétodo, mas, felizmente, você também pode colocar o código legado em um elsebloco, o que é mais limpo.
ADTC
Err ... "cláusula desonesta para pegar 1.4" ? Não deve 1.4fvoltar ao código legado?
ADTC
2
Eu sugeriria: 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 acima, código genérico abaixo, código de fallback na parte inferior.
ADTC
5

Aqui está a implementação no 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
fonte
4

Se você puder ter dependência de apache utils, poderá usar org.apache.commons.lang3.SystemUtils.

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

Aqui está a resposta de @mvanle, convertida em 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
fonte