Правильное использование параметров командной строки Java -D

147

При передаче параметра -D в Java, как правильно написать командную строку и затем получить к ней доступ из кода?

Например, я пытался написать что-то вроде этого ...

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

И затем называя это так ...

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

Но я получаю исключение NullPointerException. Что я делаю не так?

Райан Бергер
источник
рассмотрите возможность использования compareToIgnoreCaseвместо equalsIgnoreCaseлокально-независимых идентификаторов; в противном случае вы можете столкнуться с турецкой проблемой четверки, среди других.
Макдауэлл
4
Могу ли я предложить использовать Boolean.getBoolean вместо длинного оператора if? shankh.com/2009/07/07/some-fun-with-boolean-getboolean
отметьте
Что означает -D?
Anshul

Ответы:

248

Я подозреваю , что проблема в том , что вы поставить «-D» после-jar . Попробуй это:

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

Из справки командной строки:

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

Другими словами, то, как вы сейчас это получите, будет рассматриваться -Dtest="true"как один из аргументов для передачи, mainа не как аргумент JVM.

(Возможно, вам также следует отказаться от кавычек, но в любом случае это может сработать - это, вероятно, зависит от вашей оболочки.)

Джон Скит
источник
14
Работает отлично сейчас. Также интересно отметить, что для репликации этого поведения в отладчике Eclipse эти типы параметров должны быть помещены в раздел «Аргументы виртуальной машины» в разделе «Конфигурации запуска».
Райан Бергер
По крайней мере, из bash он работает там с кавычками (и также позволяет пробелы таким образом), я использую это весь день для муравьиных звонков.
Паŭло Эберманн
Чувствую себя немного глупо от того, сколько времени я потратил на это! Спасибо что подметил это. :)
Тоидиу
4
если кому-то интересно, если вы хотите передать несколько свойств, просто используйте -D несколько раз после «пробела» java -D <key1> = <value1> -D <key2> = <value2> -D <key3> = <value3 > ...
p_champ
48

Которые должны быть:

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

Затем следующее вернет значение:

System.getProperty("test");

Однако значение может быть nullтаким, поэтому защитите себя от исключения, используя Boolean:

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

Обратите внимание, что getBooleanметод делегирует значение системного свойства, упрощая код до:

if( Boolean.getBoolean( "test" ) ) {
   // ...
}
Ален Паннетье
источник
1
последний бит также справедлив для: Integer.getInteger("test"); Long.getLong("test")при условии, что у вас есть-Dtest=123
mt.uulu
23

Вы даете параметры своей программе вместо Java. использование

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

вместо.

Рассмотреть возможность использования

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

чтобы избежать NPE. Но не используйте « условия Йоды » всегда, не задумываясь, иногда бросать NPE - это правильное поведение, а иногда что-то вроде

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

верно (если задано значение по умолчанию true). Более короткая возможность

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

но не использование двойного отрицания не делает его менее трудным для неправильного понимания.

maaartinus
источник
1
На самом деле, System.getProperty("test", "true").equalsIgnoreCase("true")был бы лучший способ написать последнее условие.
Паŭло Эберманн
3
Boolean.getBoolean("test");это еще один вариант. См .
Суперфав
@Paulo Ваше решение работает только для свойств (я хотел показать общее), но лучше, чем мое.
Maaartinus
1
Интересно: в этом ответе параметр JVM идет после флага -jar, тогда как в другом ответе он идет после "java", но перед флагом -jar. Я так понимаю, что ключ к ним только в том, что параметр JVM находится перед самим файлом JAR, в данном случае «myApplication.jar»?
Колм Бхандал
1
Большие пальцы за доказательство точки зрения о двойном отрицании таким очевидным способом.
Silwing