Prawidłowe użycie parametrów wiersza poleceń Java -D

147

Podczas przekazywania parametru -D w Javie, jaki jest właściwy sposób pisania wiersza poleceń, a następnie uzyskiwania do niego dostępu z kodu?

Na przykład próbowałem napisać coś takiego ...

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

A potem nazywam to tak ...

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

Ale otrzymuję wyjątek NullPointerException. Co ja robię źle?

Ryan Berger
źródło
rozważ użycie compareToIgnoreCasezamiast equalsIgnoreCaseidentyfikatorów niezależnych od ustawień regionalnych; w przeciwnym razie możesz napotkać między innymi problem tureckiej czwórki.
McDowell,
4
Czy mogę zasugerować użycie Boolean.getBoolean zamiast długiej instrukcji if, którą masz? shankh.com/2009/07/07/some-fun-with-boolean-getboolean
znak
Co oznacza -D?
Anshul

Odpowiedzi:

248

Podejrzewam, że problemem jest to, że już umieścić „D” po-jar . Spróbuj tego:

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

Z pomocy wiersza poleceń:

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

Innymi słowy, sposób, w jaki masz to w tej chwili, będzie traktowany -Dtest="true"jako jeden z argumentów do przekazania, maina nie jako argument JVM.

(Prawdopodobnie powinieneś również porzucić cudzysłowy, ale może i tak działać - prawdopodobnie zależy to od twojej powłoki.)

Jon Skeet
źródło
14
Działa teraz idealnie. Warto również zauważyć, że w celu odtworzenia tego zachowania w debugerze Eclipse te typy parametrów muszą zostać umieszczone w sekcji Argumenty maszyny wirtualnej w sekcji Konfiguracje uruchamiania.
Ryan Berger,
Przynajmniej z basha działa z cudzysłowami (i pozwala w ten sposób spacje), używam tego przez cały dzień do wezwań mrówek.
Paŭlo Ebermann
Czuję się trochę głupio, ile czasu na to spędziłem! Dzięki za zwrócenie uwagi. :)
toidiu
4
w przypadku gdyby ktoś się zastanawiał, czy chcesz przekazać wiele właściwości, po prostu użyj -D wiele razy po 'spacji' java -D <key1> = <wartość1> -D <key2> = <wartość2> -D <key3> = <wartość3 > ...
p_champ
48

To powinno być:

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

Następnie poniższe zwrócą wartość:

System.getProperty("test");

Wartość mogłaby jednak być null, więc chroń się przed wyjątkami za pomocą Boolean:

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

Zauważ, że getBooleanmetoda deleguje wartość właściwości systemowej, upraszczając kod do:

if( Boolean.getBoolean( "test" ) ) {
   // ...
}
Alain Pannetier
źródło
1
ostatnia część dotyczy również: Integer.getInteger("test"); Long.getLong("test")zakładając, że masz-Dtest=123
mt.uulu
23

Zamiast tego podajesz parametry swojemu programowi. Posługiwać się

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

zamiast.

Rozważ użycie

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

aby uniknąć NPE. Ale nie używaj " warunków Yody " zawsze bez zastanowienia, czasami rzucanie NPE jest właściwym zachowaniem, a czasem czymś w rodzaju

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

ma rację (podając domyślną wartość true). Jest krótsza możliwość

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

ale brak podwójnej negacji nie sprawia, że ​​nieporozumienie jest mniej trudne.

maaartinus
źródło
1
Właściwie System.getProperty("test", "true").equalsIgnoreCase("true")to byłby lepszy sposób na zapisanie ostatniego warunku.
Paŭlo Ebermann
3
Boolean.getBoolean("test");to inna opcja. Zobacz .
superfav
@Paulo Twoje rozwiązanie działa tylko dla nieruchomości (chciałem pokazać ogólne), ale jest ładniejsze niż moje.
maaartinus
1
Interesujące: w tej odpowiedzi parametr JVM występuje po fladze -jar, podczas gdy w drugiej odpowiedzi występuje po opcji „java”, ale przed flagą -jar. Rozumiem więc, że kluczem jest tylko to, że parametr JVM znajduje się przed samym plikiem JAR, w tym przypadku „myApplication.jar”?
Colm Bhandal
1
Kciuki w górę za udowodnienie racji podwójnej negacji w tak oczywisty sposób.
Silwing