Это плохая практика включать файлы свойств / конфигурации в jar-файлы? - PullRequest
21 голосов
/ 30 июля 2009

Например:

MyApp - это веб-приложение, которое содержит файл свойств (server.properties), в котором описываются данные конфигурации (например, имена серверов) для приложения. На этапе разработки server.properties находится в собственной папке проекта IDE (логическая точка для этого).

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

Неделю спустя ... данные конфигурации сервера, которые использует MyApp, необходимо изменить. Что имеет больше смысла?

A. Измените файл server.properties обратно в землю IDE и создайте совершенно новый файл JAR. Переустановка. (что означает отскок приложения от простого изменения конфигурации).

B. Взломать уже развернутый Jar-файл и изменить файл server.properties? (может потребоваться вызвать функцию обновления в MyApp, если server.properties кэшируется ... но не требует полного отказа приложения. Также необходимо помнить об изменении исходного server.properties, а также при будущих развертываниях не возвращать server.properties на старые имена серверов).

C. Сначала сделайте server.properties внешним по отношению к файлу jar. Очень похоже на процесс B, с небольшим отличием в сохранении данных конфигурации вне jar (вводит разные пути между разработкой и производством развертывания)

D. Другое:

Спасибо!

Ответы [ 11 ]

18 голосов
/ 30 июля 2009

Я бы пошел с Д.

Попробуйте загрузить файлы свойств из-за пределов .jar, а затем, если это не удастся, загрузите свойства, встроенные в jar.

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

9 голосов
/ 25 сентября 2012

Если вы используете Spring, вы можете использовать заполнитель свойства для выполнения работы.

<!-- try and resolve the config from the filesystem first and then fallback to the classpath -->
<context:property-placeholder location="file:config.properties, classpath:config.properties"
                              ignore-resource-not-found="true"/>

Вы можете указать ресурс в файловой системе, а также в пути к классам, Spring сначала попытается разрешить все свойства из файловой системы, а затем откатится к пути к классам. Указав атрибут «ignore-resource-not-found» как «true», он не позволит Spring вызвать исключение, если файл отсутствует в файловой системе, и позволит вместо этого разрешить свойства из пути к классам.

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

В папке, содержащей:

application.jar
config.properties

Вы должны быть в состоянии использовать:

java -jar application.jar

Это пример config.properties для справки:

# This file contains properties that are used to configure the application
database.url=127.0.0.1
database.port=3306
database.user=root
database.pass=p4ssw0rd
5 голосов
/ 31 июля 2009

D.

Загрузить свойства в банку. Затем создайте новые свойства, используя свойства jar-ed в качестве значений по умолчанию. Затем загрузите снаружи банку. Это позволяет выбрать настройку свойств.

5 голосов
/ 30 июля 2009

Это зависит. Если файл свойств содержит данные, которые должны быть изменены пользователем вашего приложения или библиотеки, он должен находиться за пределами.

Если он содержит данные, которые являются статическими, и вы создали файлы свойств просто для того, чтобы избежать кодирования значений в исходном коде, или если файлы являются локализованными строками, я бы оставил их в банке. Хотя бы потому, что файл свойств приглашает людей изменить значения;)

3 голосов
/ 31 июля 2009

Помните, что в J2EE вам НЕ гарантирован доступ к файлам вне среды J2EE (прямой доступ к файлам отсутствует).

Вы должны будете использовать JNDI, чтобы указать на источник данных, содержащий ваши данные, или файл свойств в ваших артефактах развертывания.

Например, Websphere по умолчанию не разрешает прямой доступ к файлам.

2 голосов
/ 07 марта 2012

Вариант D. В разных средах вам может понадобиться указать, хотите ли вы указать свойства среды, такие как подключение к базе данных или прокси и т. Д.

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

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

2 голосов
/ 31 июля 2009

Часто это критерий, по которому код должен быть перенесен UNCHANGED от тестирования к производству Это означает, что вы не можете редактировать встроенные файлы конфигурации. Также вы можете оказаться в ситуации, когда вам нужно изменить развернутую конфигурацию - что часто очень громоздко. Следовательно, мы оставляем конфигурацию вне банок.

Для приложений Java EE рассмотрите JNDI или файл свойств в пути к классам.

У меня есть веб-приложение, в котором конфигурация извлекается из соседнего веб-приложения просто для их разделения. Это оказалось намного проще.

1 голос
/ 31 июля 2009

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

  • Если вам не нужен контроль версий, тогда подойдет вариант D с внешним файлом свойств, который переопределяет файл свойств. Опции B и C более открыты для наполнения, но если бы вы действительно заботились, вы бы использовали контроль версий: -)
  • Если вам нужен контроль версий, опция А дает вам больший контроль, но если у вас есть возможность нескольких развертываний, вам также может потребоваться / нужно контролировать версии для каждого развертывания. Примером являются отдельные развертывания для тестирования и рабочих платформ.

Вот как мы это делаем, используя модули Maven и «наложения» файла WAR Maven.

  1. У нас есть несколько модулей для компонентов кода Java. Это JAR-модули.
  2. У нас есть модуль "base webapp" для статического контента, JSP и данных конфигурации ядра (Spring-подключения, свойства по умолчанию). Это модуль WAR, поэтому результатом построения является WAR, содержащий вышеуказанные + все файлы JAR.
  3. Каждая отдельная «конфигурация сайта» представляет собой модуль WAR, который содержит специфичные для сайта переопределения для свойств, файлов проводки и содержимого. Переопределение описывается с использованием механизма наложения WAR для Maven и приводит к тому, что новая WAR собирается из «базовой» WAR и переопределений.

Все это проверено на контроль версий, и вам нужно выполнить сборку Maven и развертывание WAR, чтобы внести изменения в конфигурацию.

1 голос
/ 31 июля 2009

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

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

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

Обычно я делаю один WAR для тестирования, Q / A и производства и перезаписываю ресурсы, чувствительные к окружающей среде, именно так, используя xml-файлы контекста Tomcat. Я считаю, что это гораздо лучше, чем создавать несколько WAR или модифицировать WARS, поскольку тестируемое приложение практически идентично приложению, которое находится в производстве.

0 голосов
/ 31 июля 2009

Я разрабатываю приложения J2EE, используя Spring. Я бегал вокруг одной и той же проблемы довольно долго, а потом нашел решение. Моя проблема заключалась в том, чтобы указать свойства базы данных в файле свойств вне файла war, который я развернул. Решение, которое я нашел для этого, состоит в том, чтобы использовать PropertyPlaceholderConfigurer и указать свойство location для определения местоположения вашей системы, как это,

Это было довольно просто и работало просто отлично!

...