Объем свойств системы Java

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

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

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

Мои вопросы заключаются в следующем.

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

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


person Chathuranga Chandrasekara    schedule 26.05.2009    source источник


Ответы (7)


Область свойств системы

По крайней мере, из чтения спецификаций 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 потокобезопасен< /em>, поэтому я ожидал, что Properties будет таким же, и на самом деле Спецификации API для Properties подтверждает это:

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

person coobird    schedule 26.05.2009

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

person Max Nanasy    schedule 30.08.2013
comment
@Dejel Они не являются локальными для потока. Все потоки в одном процессе JVM имеют общий набор значений системных свойств. - person Max Nanasy; 31.12.2014

Для каждой виртуальной машины существует одна копия свойств. У них почти те же проблемы, что и у других статических объектов (включая синглтоны).

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

person Tom Hawtin - tackline    schedule 26.05.2009

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

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

person Laurence Gonsalves    schedule 26.05.2009

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

person Yishai    schedule 26.05.2009

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

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

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

person Fortyrunner    schedule 26.05.2009

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

person Robin73    schedule 26.10.2017
comment
Моя проблема была решена, прочитав это: stackoverflow.com/a/19362517/7662731 - person Robin73; 26.10.2017