Penggunaan yang benar dari parameter baris perintah Java -D

147

Ketika melewati parameter -D di Java, apa cara yang tepat untuk menulis baris perintah dan kemudian mengaksesnya dari kode?

Misalnya, saya sudah mencoba menulis sesuatu seperti ini ...

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

Dan kemudian menyebutnya seperti ini ...

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

Tapi saya menerima NullPointerException. Apa yang saya lakukan salah?

Ryan Berger
sumber
pertimbangkan untuk menggunakan compareToIgnoreCasealih-alih equalsIgnoreCaseuntuk pengidentifikasi lokal-agnostik; jika tidak, Anda dapat mengalami masalah empat-Turki, antara lain.
McDowell
4
Bolehkah saya menyarankan menggunakan Boolean.getBoolean daripada panjang jika-pernyataan yang Anda miliki? shankh.com/2009/07/07/some-fun-with-boolean-getboolean
tandai
Apa kepanjangan -D?
Anshul

Jawaban:

248

Saya menduga masalahnya adalah Anda telah meletakkan "-D" setelah tanda -jar. Coba ini:

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

Dari bantuan baris perintah:

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

Dengan kata lain, cara Anda mendapatkannya saat ini akan memperlakukan -Dtest="true"sebagai salah satu argumen untuk diteruskan mainalih-alih sebagai argumen JVM.

(Anda mungkin juga harus memberikan tanda kutip, tetapi mungkin juga bisa berhasil - itu mungkin tergantung pada shell Anda.)

Jon Skeet
sumber
14
Bekerja dengan baik sekarang. Yang juga menarik untuk dicatat adalah bahwa untuk mereplikasi perilaku ini di dalam Eclipse debugger, jenis-jenis parameter ini harus ditempatkan di bagian VM Arguments di bawah Run Configurations.
Ryan Berger
Setidaknya dari bash berfungsi dengan tanda kutip di sana (dan juga memungkinkan spasi dengan cara ini), saya menggunakan ini sepanjang hari untuk ant-panggilan.
Paŭlo Ebermann
Merasa agak bodoh berapa banyak waktu yang saya habiskan untuk yang satu itu! Terima kasih telah menunjukkannya. :)
toidiu
4
dalam kasus seseorang bertanya-tanya, jika Anda ingin melewati beberapa properti cukup gunakan -D beberapa kali setelah java 'spasi' -D <key1> = <value1> -D <key2> = <value2> -D <key3> = <value3 > ...
p_champ
48

Itu harus:

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

Maka yang berikut akan mengembalikan nilainya:

System.getProperty("test");

Namun, nilainya bisa nulljadi waspada terhadap pengecualian menggunakan Boolean:

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

Perhatikan bahwa getBooleanmetode ini mendelegasikan nilai properti sistem, menyederhanakan kode untuk:

if( Boolean.getBoolean( "test" ) ) {
   // ...
}
Alain Pannetier
sumber
1
bit terakhir juga berlaku untuk: Integer.getInteger("test"); Long.getLong("test")dengan asumsi Anda memiliki-Dtest=123
mt.uulu
23

Sebagai gantinya, Anda memberikan parameter ke program Anda ke Java. Menggunakan

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

sebagai gantinya.

Pertimbangkan untuk menggunakan

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

untuk menghindari NPE. Tapi jangan gunakan " kondisi Yoda " selalu tanpa berpikir, kadang-kadang melempar NPE adalah perilaku yang benar dan kadang-kadang sesuatu seperti

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

benar (memberikan standar yang benar). Kemungkinan yang lebih pendek adalah

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

tetapi tidak menggunakan negasi ganda tidak membuatnya lebih sulit untuk disalahpahami.

maaartinus
sumber
1
Sebenarnya, System.getProperty("test", "true").equalsIgnoreCase("true")akan menjadi cara yang lebih baik untuk menulis kondisi terakhir.
Paŭlo Ebermann
3
Boolean.getBoolean("test");adalah pilihan lain. Lihat .
superfav
@ Paulo Solusi Anda hanya berfungsi untuk properti (saya ingin menunjukkan yang umum) tetapi lebih bagus daripada milik saya.
maaartinus
1
Menarik: Dalam jawaban ini parameter JVM muncul setelah flag -jar, sementara di jawaban lain ia muncul setelah "java" tetapi sebelum flag -jar. Saya mengambil kemudian bahwa kunci mereka hanya bahwa parameter JVM datang sebelum file JAR itu sendiri, dalam hal ini "myApplication.jar"?
Colm Bhandal
1
Jempol untuk membuktikan poin tentang negasi ganda dengan cara yang jelas.
Silwing