Uso adequado dos parâmetros da linha de comandos Java -D

147

Ao passar um parâmetro -D em Java, qual é a maneira correta de escrever a linha de comando e acessá-la a partir do código?

Por exemplo, eu tentei escrever algo assim ...

if (System.getProperty("test").equalsIgnoreCase("true"))
{
   //Do something
}

E então chamando assim ...

java -jar myApplication.jar -Dtest="true"

Mas eu recebo uma NullPointerException. O que estou fazendo de errado?

Ryan Berger
fonte
considere usar em compareToIgnoreCasevez de equalsIgnoreCasepara identificadores independentes de localidade; caso contrário, você pode se deparar com o problema turco de quatro is, entre outros.
McDowell
4
Posso sugerir o uso de Boolean.getBoolean em vez da declaração if longa que você possui? shankh.com/2009/07/07/some-fun-with-boolean-getboolean
marca
-D de quê?
Anshul

Respostas:

248

Eu suspeito que o problema é que você colocou o "-D" após o -jar. Tente o seguinte:

java -Dtest="true" -jar myApplication.jar

Na ajuda da linha de comandos:

java [-options] -jar jarfile [args...]

Em outras palavras, o modo como você o obteve no momento será tratado -Dtest="true"como um dos argumentos a serem passados, e mainnão como um argumento da JVM.

(Você provavelmente também deve soltar as aspas, mas pode funcionar de qualquer maneira - provavelmente depende do seu shell.)

Jon Skeet
fonte
14
Funciona perfeitamente agora. Também é interessante notar que, para replicar esse comportamento no depurador Eclipse, esses tipos de parâmetros devem ser colocados na seção Argumentos da VM em Configurações de execução.
Ryan Berger
Pelo menos do bash ele trabalha com as aspas (e também permite espaços dessa maneira), eu uso isso o dia todo para chamadas de formiga.
Pa Elo Ebermann
Me sinto meio idiota por quanto tempo eu passei nessa! Obrigado por apontar isso. :)
toidiu 13/08/16
4
caso alguém esteja se perguntando, se você deseja passar várias propriedades, use -D várias vezes após um 'espaço' java -D <key1> = <value1> -D <key2> = <value2> -D <key3> = <value3 > ...
p_champ 10/10
48

Isso deve ser:

java -Dtest="true" -jar myApplication.jar

Em seguida, o seguinte retornará o valor:

System.getProperty("test");

O valor pode ser null, no entanto, para evitar uma exceção usando um Boolean:

boolean b = Boolean.parseBoolean( System.getProperty( "test" ) );

Observe que o getBooleanmétodo delega o valor da propriedade do sistema, simplificando o código para:

if( Boolean.getBoolean( "test" ) ) {
   // ...
}
Alain Pannetier
fonte
1
último bit também é válido para: Integer.getInteger("test"); Long.getLong("test")supondo que você tem-Dtest=123
mt.uulu
23

Você está dando parâmetros ao seu programa em vez de Java. Usar

java -Dtest="true" -jar myApplication.jar 

em vez de.

Considere usar

"true".equalsIgnoreCase(System.getProperty("test"))

para evitar o NPE. Mas não use " condições Yoda " sempre sem pensar, às vezes jogando o NPE é o comportamento certo e às vezes algo como

System.getProperty("test") == null || System.getProperty("test").equalsIgnoreCase("true")

está correto (fornecendo o padrão true). Uma possibilidade mais curta é

!"false".equalsIgnoreCase(System.getProperty("test"))

mas não usar a dupla negação não torna menos difícil entender mal.

maaartinus
fonte
1
Na verdade, System.getProperty("test", "true").equalsIgnoreCase("true")seria a melhor maneira de escrever a última condição.
Pa Elo Ebermann 18/02
3
Boolean.getBoolean("test");é outra opção. Veja .
superfav
@Paulo Sua solução funciona apenas para propriedades (eu queria mostrar uma solução geral), mas é mais agradável que a minha.
Maaartinus
1
Interessante: nesta resposta, o parâmetro JVM vem após o sinalizador -jar, enquanto na outra resposta vem após o "java", mas antes do sinalizador -jar. Entendo que eles chave é apenas que o parâmetro JVM vem antes do próprio arquivo JAR, neste caso "myApplication.jar"?
Colm Bhandal
1
Polegares para cima para provar o ponto sobre dupla negação de uma maneira tão óbvia.
Silwing