Внешняя настройка Tomcat webapp config из файла .war
У меня проблемы с настройкой веб-приложения в Tomcat 7. В моем WAR файле есть файл свойств myApp/WEB-INF/classes/myProps.props
, и он содержит специфические для среды свойства. Я пытаюсь переопределить этот файл конфигурации на сервере, чтобы один и тот же WAR файл был развернут в нескольких средах.
Я слышал, что есть способ сделать это, используя файлы конфигурации замены в tomcat/conf/Catalina/myApp
. Это метод, который мне трудно понять.
Кроме того, myApp.war
является одним из многих, работающих на одном сервере Tomcat, и он не работает как myApp.war
. Я хочу быть в состоянии решить эту проблему для нескольких веб-приложений.
Server version: Apache Tomcat/7.0.23
Server built: Nov 20 2011 07:36:25
Server number: 7.0.23.0
OS Name: Linux
Ответы
Ответ 1
Ваш tomcat/conf/Catalina/<host>
может содержать дескрипторы контекста, которые позволяют вам конфигурировать множество вещей, включая определение "записей среды", которые доступны из Java через JNDI. Есть много способов использовать его. Лично я установил запись среды, которая представляет собой путь файловой системы к моему файлу свойств. Мое приложение создано для проверки этой записи, и, если она не существует, вместо этого найдите файл в classpath. Таким образом, в dev у нас есть свойства dev прямо на пути к классам, но когда мы собираем и внедряем, мы указываем на внешний файл.
Там хорошая документация для настройки контекста на сайте Tomcat. См. Раздел " Определение контекста", где подробно описано, как создать файл и где его разместить.
Например, если ваш хост называется myHost
а ваше приложение представляет собой файл war с именем myApp.war
в каталоге webapps
, то вы можете создать tomcat/conf/Catalina/myHost/myApp.xml
со следующим содержимым:
<Context>
<Environment name="configurationPath" value="/home/tomcat/myApp.properties" type="java.lang.String"/>
</Context>
Затем из вашего кода вы должны выполнить поиск JNDI для java:comp/env/configurationPath
(здесь 95% -ная уверенность), чтобы получить это строковое значение.
Ответ 2
Мне нравятся файлы .properties
вместо
- JNDI - зачем строить сложный объект во время конфигурации программы, а не во время инициализации?
- системные свойства - вы не можете отдельно настроить несколько экземпляров одной и той же WAR в одном Tomcat
- параметры контекста - они доступны только в
javax.servlet.Filter
, javax.servlet.ServletContextListener
которые могут быть неудобны
Tomcat 7 Context содержит элемент Loader. В соответствии с дескриптором развертывания документов (что в <Context>
) можно разместить в:
-
$CATALINA_BASE/conf/server.xml
- плохо - требует перезапуска сервера для перечитывания конфигурации -
$CATALINA_BASE/conf/context.xml
- плохо - используется всеми приложениями -
$CATALINA_BASE/work/$APP.war: /META-INF/context.xml
- плохо - требуется переупаковка для изменения конфигурации -
$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml
- хорошо, но смотрите последний вариант !! -
$CATALINA_BASE/webapps/$APP/META-INF/context.xml
- хорошо, но смотрите последний вариант !! -
$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml
- лучше всего - полностью вне приложения и автоматически сканируется на наличие изменений !!!
Context
может содержать пользовательский Loader
org.apache.catalina.loader.VirtualWebappLoader (доступный в современном Tomcat 7, вы можете добавить собственный отдельный путь к классу для ваших .properties
) и Parameter
(доступный через FilterConfig.getServletContext().getInitParameter(name)
) и Environment
(доступ через new InitialContext().lookup("java:comp/env").lookup("name")
):
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
Если вы используете Spring и его XML config:
<context:property-placeholder location="classpath:app.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
</bean>
С помощью Spring вводить указанные выше свойства в поля компонента легко:
@Value("${db.user}") String defaultSchema;
вместо JNDI:
@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");
Также обратите внимание, что EL допускает это (значения по умолчанию и глубокая рекурсивная замена):
@Value('${db.user:testdb}') private String dbUserName;
<property name='username' value='${db.user.${env}}'/>
Смотрите также:
ПРИМЕЧАНИЕ. Расширяя classpath до действующего каталога, вы также разрешаете экстернилировать любые другие настройки, такие как logging, auth, atc. Я externilize logback.xml
таким образом.
ОБНОВЛЕНИЕ Tomcat 8 изменяет синтаксис для элементов <Resources>
и <Loader>
, соответствующая часть теперь выглядит следующим образом:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
Ответ 3
Вы можете попробовать разместить свою конфигурацию (файл свойств) в Apache Tomcat\lib в файле JAR и удалить ее из веб-приложения. Когда загрузчик класса Tomcat не найдет вашу конфигурацию в webapp, он попытается найти в каталоге "lib". Таким образом, вы можете экстернализировать свою конфигурацию, просто переместив конфигурацию в глобальный lib dir (она была распространена среди других webapps).
Ответ 4
Я только что добавил сценарий setenv.bat
или setenv.sh
в папку bin
на tomcat. Установите переменную classpath
как
set CLASSPATH=my-propery-folder