Как я могу хранить параметры конфигурации Java EE вне уха или войны?

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

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

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

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

5 ответов


посмотреть этот вопрос для чтения файла свойств вне файла 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.
  • параметры легко настраиваются в контейнер.
  • вам не нужно перезапускать контейнер при изменении значения параметра.

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

1) только простые записи name=value должны быть используется

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

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

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

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

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

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

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


Я использую переменную среды, чтобы указать 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");
   }



}

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

Это просто и довольно просто.. если только я чего-то не упустил!--1-->


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

таблица базы данных, хранящая свойства среды

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

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

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