Как определить, исходит ли системное свойство от оператора-человека, а не по умолчанию?

У меня есть автономное приложение, упакованное в JAR, которое при выполнении распаковывает себя во временный каталог и порождает дочерний процесс в этом каталоге. Причина в том, что какой-то сторонний код и конфигурация предполагают, что файлы данных находятся относительно текущего рабочего каталога, а в java нет метода chdir(), поэтому единственный способ - переключить рабочий каталог для дочернего процесса.

Все работает нормально, кроме системных свойств. Оператор может принять решение указать в командной строке некоторые свойства системы, как стандартные, так и связанные со сторонней конфигурацией:

java -Djava.io.tmpdir=/temp -Dsomething=else -jar foo.jar (parameters)

Системные свойства, доступные родительскому процессу Java, по умолчанию не распространяются на дочерний процесс. Я должен сделать это сам. И здесь у меня возникает препятствие: я не могу сказать, какие свойства устанавливаются оператором, а какие по умолчанию инициализируются JVM.

Возьмите этот java.io.tmpdir. Если оператор предоставил его, у него есть веская причина для этого (возможно, расположение по умолчанию — «диск заполнен»). Я должен установить его как дочерний процесс, иначе он потерпит неудачу. Но как я узнаю, пришло ли оно от оператора? Это может быть просто значение по умолчанию.

Я могу попробовать установить все доступные системные свойства для дочернего процесса. Однако это занимает длинный список и, что еще хуже, не работает в некоторых средах, где длина командной строки ограничена.

Единственный обходной путь, который я нашел до сих пор (довольно злой), - это сначала создать еще один дочерний процесс без каких-либо аргументов и позволить ему передать родителю все системные свойства, которые у него есть. Значения, которые соответствуют значениям родительского элемента, являются значениями по умолчанию. Остальное должно быть передано рабочему дочернему процессу.

У кого-нибудь есть лучшая альтернатива?


person Vladimir Dyuzhev    schedule 12.05.2011    source источник


Ответы (3)


Там, где я работаю, у нас был медленно растущий список системных свойств, которые могли применять пользователи, и хотя у нас не было дочерних процессов, о которых нужно было беспокоиться, у нас была другая проблема: их было слишком много.

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

Если бы вы смогли убедить пользователей поставить туда постоянные свойства, а затем запустить процесс запуска дочернего процесса, а затем загрузки из файла, то можно было бы вообще избежать головной боли.

Тем не менее, вам, скорее всего, будут представлены сценарии отладки, в которых желательны временные или одноразовые свойства без изменения файла (не то, чтобы это действительно имело большое значение). Здесь у вас есть несколько вариантов:

  1. Продолжайте использовать подход, который вы используете сейчас.
  2. Попросите пользователя передать системные свойства в качестве аргументов командной строки, которые вы затем загружаете в системные свойства как для родительского, так и для дочернего процесса.
  3. Скажи жестко, используй файл. (Не страшно, но меня как пользователя такое решение раздражало бы)
person pickypg    schedule 12.05.2011

Я не думаю, что есть хороший ответ на это. Но, к счастью, большинство стандартных свойств системы либо нельзя переопределить, либо никто в здравом уме не стал бы переопределять.

Таким образом, следующие подходы, вероятно, являются вашими лучшими ставками:

  • передать подмножество стандартных свойств, которые, по вашему мнению, имеет смысл передать,
  • предоставить способ указать параметры JVM (включая параметры -D), которые будут использоваться для дочерних JVM, или
  • сочетание вышеперечисленных подходов.
person Stephen C    schedule 12.05.2011

Выбранное решение:

Мне по-прежнему приходилось использовать дочерний процесс, который ничего не делает, кроме как передает родительскому все системные свойства, которые он может сравнить. Единственная незначительная проблема, на которую я наткнулся, это свойство line.separator, из-за которого мой код чтения строк натыкался на лишнюю пустую строку. Это было легко исправить.

Почему я не принял ни один ответ:

Подходы, предложенные в ответах ниже, разумны, но ни один из них не является полностью удовлетворительным.

У меня нет большой власти над пользователями, чтобы сказать им, что системные свойства Java должны передаваться через файл свойств или специальный аргумент командной строки. Это неудобно и противоречит практике эксплуатации (особые случаи всегда плохи).

Я также не могу выбрать подмножество системных свойств для передачи дочернему процессу. В документации по системным классам не указано, какие из них можно перезаписывать (и здравый смысл не заменяет никакой документации). Существует также средство для конечного пользователя, чтобы определить свои собственные свойства, и те, которые я не могу предсказать ни по имени, ни по номеру.

person Vladimir Dyuzhev    schedule 23.05.2011