Область применения свойств системы Java - PullRequest
45 голосов
/ 26 мая 2009

В Java мы используем метод System.setProperty () для установки некоторых системных свойств. Согласно этой статье использование системных свойств немного сложнее.

System.setProperty () может быть злым вызовом.

  • Это 100% враждебный поток
  • Содержит суперглобальные переменные
  • Чрезвычайно сложно отладить эти загадочные переменные изменить во время выполнения.

Мои вопросы следующие.

  1. Как насчет области свойств системы? Они специфичны для каждой виртуальной машины или имеют «суперглобальную природу», которая имеет одинаковый набор свойств для каждого экземпляра виртуальной машины? Я думаю, вариант 1

  2. Существуют ли какие-либо инструменты, которые можно использовать для отслеживания изменений во время выполнения для обнаружения изменений в свойствах системы. (Только для простоты обнаружения проблем)

Ответы [ 7 ]

41 голосов
/ 26 мая 2009

Сфера свойств системы

По крайней мере, прочитав спецификации API для метода System.setProperties, я не смог получить ответ, являются ли системные свойства общими для всех экземпляров JVM или нет.

Чтобы выяснить это, я написал две быстрые программы, которые будут устанавливать системное свойство через System.setProperty, используя тот же ключ, но разные значения:

class T1 {
  public static void main(String[] s) {
    System.setProperty("dummy.property", "42");

    // Keep printing value of "dummy.property" forever.
    while (true) {
      System.out.println(System.getProperty("dummy.property"));
      try {
        Thread.sleep(500);
      } catch (Exception e) {}
    }
  }
}

class T2 {
  public static void main(String[] s) {
    System.setProperty("dummy.property", "52");

    // Keep printing value of "dummy.property" forever.
    while (true) {
      System.out.println(System.getProperty("dummy.property"));
      try {
        Thread.sleep(500);
      } catch (Exception e) {}
    }
  }
}

(Остерегайтесь того, что запуск двух вышеперечисленных программ приведет их в бесконечный цикл!)

Оказывается, при запуске двух программ с использованием двух отдельных процессов java значение свойства, установленное в одном процессе JVM, не влияет на значение другого процесса JVM.

Я должен добавить, что это результаты использования Sun JRE 1.6.0_12, и это поведение не определено, по крайней мере, в спецификациях API (или я не смог его найти), поведение может отличаться.

Существуют ли инструменты для отслеживания изменений во время выполнения

Не в моих силах. Однако, если нужно проверить, были ли изменения в системных свойствах, можно одновременно удержать копию Properties и сравнить ее с другим вызовом System.getProperties - в конце концов, Properties является подклассом Hashtable, поэтому сравнение будет выполняться аналогичным образом.

Ниже приведена программа, которая демонстрирует способ проверки наличия изменений в системных свойствах. Вероятно, не элегантный метод, но, кажется, делает свою работу:

import java.util.*;

class CheckChanges {

  private static boolean isDifferent(Properties p1, Properties p2) {
    Set<Map.Entry<Object, Object>> p1EntrySet = p1.entrySet();
    Set<Map.Entry<Object, Object>> p2EntrySet = p2.entrySet();

    // Check that the key/value pairs are the same in the entry sets
    // obtained from the two Properties.
    // If there is an difference, return true.
    for (Map.Entry<Object, Object> e : p1EntrySet) {
      if (!p2EntrySet.contains(e))
        return true;
    }
    for (Map.Entry<Object, Object> e : p2EntrySet) {
      if (!p1EntrySet.contains(e))
        return true;
    }

    return false;
  }

  public static void main(String[] s)
  {
    // System properties prior to modification.
    Properties p = (Properties)System.getProperties().clone();
    // Modification of system properties.
    System.setProperty("dummy.property", "42");
    // See if there was modification. The output is "false"
    System.out.println(isDifferent(p, System.getProperties()));
  }
}

Свойства не поточнобезопасны?

Hashtable является поточно-ориентированным , поэтому я ожидал, что Properties также будет, и фактически, спецификации API для Properties класс подтверждает это:

Этот класс является поточно-ориентированным: несколько темы могут делиться одним Properties объект без необходимости внешнего синхронизация., Сериализованная форма

9 голосов
/ 30 августа 2013

Системные свойства для каждого процесса. Это означает, что они являются более глобальными, чем статические поля, которые являются для каждого загрузчика классов. Так, например, если у вас есть один экземпляр Tomcat, на котором запущено несколько веб-приложений Java, каждый из которых имеет класс com.example.Example со статическим полем с именем globalField, тогда веб-приложения будут иметь общие системные свойства, но можно установить com.example.Example.globalField к другому значению в каждом веб-приложении.

4 голосов
/ 26 мая 2009

Существует одна копия свойств на ВМ. Они имеют те же проблемы, что и другие статики (включая синглтоны).

Полагаю, в качестве хака вы вызываете System.setProperties для версии Properties, которая реагирует по-разному в зависимости от контекста (поток, стек вызовов, время суток и т. Д.). Он также может регистрировать любые изменения с System.setProperty. Вы также можете установить SecurityManager проверки безопасности журналов для соответствующих разрешений.

3 голосов
/ 26 мая 2009

Их область действия - работающая JVM, но если у вас нет какого-либо эзотерического загрузчика классов, статическая переменная с объектом свойств сделает то же самое и с возможностью синхронизировать или сделать все, что вам нужно.

3 голосов
/ 26 мая 2009

Да, «системные свойства» относятся к каждой виртуальной машине (хотя существует ряд «магических» свойств, которые содержат информацию о хост-системе, например: «os.name», «os.arch» и т. Д.).

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

0 голосов
/ 26 октября 2017

Когда вы запускаете новую JVM, она создает копию переменных среды и использует их для всего жизненного цикла. Так что, если вы внесете изменения в эту среду, они останутся ограничены этим. Странное поведение, с которым я столкнулся и которое я исследую, немного отличается: если я запускаю JVM, объявляющую некоторые переменные среды (аргумент -D в строке cmd), которые влияют на поведение библиотек, которые я использую в своих приложениях. Но если внутри java-кода (там, где они видны) я внесу в них изменения, кажется, что эти изменения не влияют на поведение библиотек. Странно, что мы в одной JVM!

0 голосов
/ 26 мая 2009

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

Мы используем Spring для нашей конфигурации и устанавливаем начальные свойства, используя файл свойств, который внедряется в XML. Изменения в конфигурации во время работы приложения производятся с использованием JMX.

Существует, конечно, много других способов изменить конфигурацию в Java с помощью файла свойств, конфигурации на основе xml и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...