Как сохранить параметры конфигурации Java EE за пределами EAR или WAR?
Я хочу сохранить конфигурацию для веб-проекта вне веб-проекта (файл уха/войны).
Приложение не должно знать, в каком контейнере он работает (WebSphere/JBoss и т.д.).
Каков наилучший способ справиться с этим?
Является ли JNDI чистым способом? Если JNDI может решить мои проблемы, как его настроить? (Пользовательские объекты?)
В моем случае есть только простые пары Key = > Value (String, String) для конечных точек SOAP/WS.
Ответы
Ответ 1
Смотрите этот question для чтения файла свойств вне WAR файла.
См. question для чтения значений переменных из JNDI. Я считаю, что это лучшее решение. Вы можете прочитать переменную String с помощью этого кода:
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.
- Параметры легко настраиваются в контейнере.
- Вам не нужно перезапускать контейнер при изменении значения параметра.
Ответ 2
У нас было аналогичное требование конфигурации при развертывании webapp для разных разработчиков и на Amazon EC2: как мы отделяем конфигурацию от двоичного кода? По моему опыту, JNDI слишком сложна и слишком сильно различается между используемыми контейнерами. Кроме того, редактирование вручную XML очень восприимчиво к синтаксическим ошибкам, поэтому идея была выбрана. Мы решили это с помощью дизайна, основанного на нескольких правилах:
1) следует использовать только простую запись name = value
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 с помощью точно одного набора скомпилированных двоичных файлов, используя различные конфигурации в каждой среде. Там нет риска наличия паролей /etc в двоичных файлах, и люди могут делиться своими конфигурациями, чтобы воссоздать проблемы, которые мы видим.
Ответ 3
Я использую переменную окружения, указывающую на 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");
}
}
Ответ 4
который вы можете просто сохранить, является нормальным файлом свойств java, который находится на пути к классу и просто загружает свойства?
это просто и довольно просто.. если я что-то не хватает
Ответ 5
Моими любимыми местами являются: переменные среды и файлы свойств (как было предложено Джаредом и кганнакакисом выше).
Свойства хранилища таблиц базы данных
Однако другие простые решения заключаются в том, что таблица базы данных хранит свойства среды.
Если ваше приложение использует базу данных
- это относительно просто настроить
- Дает действительно простой способ управления/изменения значений
- Он может быть интегрирован в процесс хорошо, сделав его частью сценариев БД