Как я могу сохранить параметры конфигурации Java EE вне EAR или WAR? - PullRequest
36 голосов
/ 08 июня 2009

Я хочу сохранить конфигурацию для веб-проекта вне веб-проекта (файл ear / war). Приложение не должно знать, в каком контейнере оно работает (WebSphere / JBoss и т. Д.).

Каков наилучший способ справиться с этим?

Является ли JNDI чистым способом? Если JNDI может решить мои проблемы, как мне это настроить? (Пользовательские объекты?)

В моем случае для конечных точек SOAP / WS есть только простые пары Key => Value (String, String).

Ответы [ 5 ]

27 голосов
/ 11 июня 2009

См. Этот вопрос для чтения файла свойств вне файла WAR.

См. Этот вопрос для чтения значений переменных из JNDI. Я считаю, что это лучшее решение. Вы можете прочитать строковую переменную с помощью этого кода:

Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("java:comp/env/myvar");

Приведенный выше код будет работать на всех контейнерах. В Tomcat вы заявляете следующее в conf / server.xml:

<GlobalNamingResources ...>
  <Environment name="myvar" value="..."
         type="java.lang.String" override="false"/>
</GlobalNamingResources>

Выше будет создан глобальный ресурс. Также возможно определить ресурс в контексте приложения. В большинстве контейнеров ресурсы JNDI доступны через консоль управления MBeans. Некоторые из них предлагают графический интерфейс для их редактирования. Максимально требуется перезапуск приложения после внесения изменений.

Способ определения и редактирования ресурсов JNDI зависит от контейнера. Конфигуратор / администратор должен применять соответствующие настройки.

Вот преимущества, предлагаемые JNDI:

  • Вы можете определить значения параметров по умолчанию в файле WAR / EAR.
  • Параметры легко настраиваются в контейнере.
  • Вам не нужно перезапускать контейнер при изменении значения параметра.
11 голосов
/ 18 июня 2009

У нас было похожее требование к конфигурации при развертывании веб-приложения для разных разработчиков и на Amazon EC2: как мы отделим конфигурацию от двоичного кода? По моему опыту, JNDI слишком сложен и слишком сильно варьируется между контейнерами для использования. Кроме того, ручное редактирование XML очень восприимчиво к синтаксическим ошибкам, поэтому эта идея была отброшена. Мы решили это с помощью дизайна, основанного на нескольких правилах:

1) должны использоваться только простые имена = значения

2) новые конфигурации должны быть загружены путем изменения только одного параметра

3) наш WAR-файл должен быть реконфигурируемым без повторной упаковки

4) конфиденциальные параметры (пароли) никогда не будут упакованы в двоичный файл

Используя файлы .properties для всех настроек и используя System.getProperty("domain"); для загрузки соответствующих файлов свойств, мы смогли удовлетворить требования. Однако системное свойство не указывает на URL-адрес файла, вместо этого мы создали концепцию, которую мы называем «домен», чтобы указать используемую конфигурацию. Расположение конфигурации всегда:
$HOME/appName/config/$DOMAIN.properties.

Поэтому, если я хочу запустить свое приложение, используя мою собственную конфигурацию, я запускаю приложение, задав домену свое имя:
-Ddomain=jason
при запуске приложение загружает файл:
/home/jason/appName/config/jason.properties
Это позволяет разработчикам совместно использовать конфигурации, чтобы мы могли воссоздать одно и то же состояние приложения для тестирования и развертывания без перекомпиляции или повторной упаковки. Затем значение домена используется для загрузки .properties из стандартного местоположения вне объединенного WAR.

Я могу полностью воссоздать производственную среду на своей рабочей станции, используя производственную конфигурацию, например:
-Ddomain=ec2 который загрузит:
/home/jason/appName/config/ec2.properties

Эта настройка позволяет нам иметь циклы dev / QA / release с точно-одним набором скомпилированных двоичных файлов, используя различные конфигурации в каждой среде. Нет риска, что пароли и т. Д. Будут связаны в двоичных файлах, и люди могут поделиться своими конфигурациями, чтобы воссоздать проблемы, которые мы наблюдаем.

10 голосов
/ 08 июня 2009

Я использую переменную среды, чтобы указать на URL (который, вероятно, является файлом: // URL), в котором есть моя конфигурация. Это очень просто настроить и не требует инфраструктуры JNDI.

Вот пример кода (набранный из памяти - я не скомпилировал / не протестировал это):

public void loadConfiguration() {
   String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more
                                                      // Specific variable name.
   if(configUrlStr == null || configUrlStr.equals("") {
       // You would probably want better exception handling, too.
       throw new RuntimeException("CONFIG_URL is not set in the environment."); 
   }


   try {
       URI uri = new URI(configUrlStr);
       File configFile = new File(uri);
       if(!configFile.exists()) {
          throw new RuntimeException("CONFIG_URL points to non-existant file");
       }
       if(!configFile.canRead()) {
          throw new RuntimeException("CONFIG_URL points to a file that cannot be read.");
       }
       this.readConfiguration(configFile);
   } catch (URISyntaxException e) {
       throw new RuntimeException("Malformed URL/URI in CONFIG_URL");
   }



}
9 голосов
/ 13 июня 2009

Вы можете просто сохранить обычный файл свойств Java, который находится на пути к классу, и просто загрузить свойства?

это просто и довольно просто .. если я что-то упустил

4 голосов
/ 11 июня 2009

Мои любимые места: файлы переменных и свойств среды (как предложено Джаредом и Кгианнакакисом выше).

Таблица базы данных со свойствами среды

Однако еще одно более простое решение - иметь таблицу базы данных, в которой хранятся свойства среды.

Если ваше приложение использует базу данных

  • это относительно просто настроить
  • Дает действительно простой способ управления / изменения значений
  • Его можно хорошо интегрировать в процесс, сделав его частью сценариев БД
...