Externalización de la configuración de la aplicación de Tomcat desde el archivo .war

Tengo problemas para configurar una aplicación web en tomcat 7. En mi archivo war, hay un archivo de propiedades myApp / WEB-INF / classes / myProps.props, y contiene las propiedades propias del entorno. Estoy tratando de anular ese archivo de configuración en el servidor, de modo que el mismo archivo de guerra se implemente en múltiples entornos.

Escuché que había una forma de hacerlo utilizando los archivos de configuración de reemplazo en tomcat / conf / Catalina / myApp. Este es el método que estoy teniendo problemas para descubrir.

Además, myApp.war es uno de los muchos que se ejecuta en el mismo servidor de tomcat, y no se ejecuta como localhost. Quiero ser capaz de resolver este problema para varias de las aplicaciones web.

Server version: Apache Tomcat/7.0.23 Server built: Nov 20 2011 07:36:25 Server number: 7.0.23.0 OS Name: Linux 

Your tomcat/conf/Catalina/ puede contener descriptores de contexto que le permiten configurar muchas cosas, incluida la definición de “entradas de entorno”, a las que se puede acceder desde Java a través de JNDI. Hay muchas maneras de usarlo. Personalmente, establezco una entrada de entorno que es la ruta del sistema de archivos a mi archivo de propiedades. Mi aplicación está diseñada para comprobar esta entrada, y si no existe, busque el archivo en la ruta de clases en su lugar. De esta forma, en dev, tenemos las propiedades de desarrollo justo en el classpath, pero cuando construimos e implementamos, lo señalamos a un archivo externo.

Hay una buena documentación para configurar un contexto en el sitio web de Tomcat. Consulte la sección “Definición de un contexto” sobre los detalles de cómo crear el archivo y dónde colocarlo.

Como ejemplo, si su host se llama “myHost” y su aplicación es un archivo war llamado “myApp.war” en el directorio webapps, entonces puede crear tomcat/conf/Catalina/myHost/myApp.xml con este contenido:

    

Luego, desde su código, haría una búsqueda JNDI en java:comp/env/configurationPath (95% de certeza aquí) para obtener ese valor de cadena.

Me gustan los archivos .properties lugar de

  • JNDI: ¿por qué construir objetos complejos durante la configuración del progtwig en lugar del tiempo de inicialización?
  • propiedades del sistema: no puede configurar por separado varias instancias de la misma GUERRA en Tomcat individual
  • parámetros de contexto: solo se puede acceder a ellos en javax.servlet.Filter , javax.servlet.ServletContextListener , que puede ser un inconveniente

Tomcat 7 Context hold Loader element. De acuerdo con el descriptor de implementación de documentos (lo que en la etiqueta ) se puede colocar en:

  • $CATALINA_BASE/conf/server.xml – bad – require server reinicia para volver a leer config
  • $CATALINA_BASE/conf/context.xml – malo – compartido en todas las aplicaciones
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml – bad – requiere reempaquetado para cambiar las configuraciones
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml – ¡¡¡ bien , pero mira la última opción !!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xml – ¡ $CATALINA_BASE/webapps/$APP/META-INF/context.xml , pero mira la última opción!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml – lo mejor – completamente fuera de aplicación y escaneado automáticamente en busca de cambios.

Context puede contener el Loader personalizado org.apache.catalina.loader.VirtualWebappLoader (disponible en el moderno Tomcat 7, puede agregar su propio classpath por separado a sus .properties ), y el Parameter (al que se accede a través de FilterConfig.getServletContext().getInitParameter(name) ) y Environment (se accede a través de la new InitialContext().lookup("java:comp/env").lookup("name") ):

          

Si usa Spring y su configuración XML:

        

Con Spring inyectando las propiedades anteriores en los campos de frijol es fácil:

 @Value("${db.user}") String defaultSchema; 

en lugar de JNDI:

 @Inject ApplicationContext context; Enviroment env = context.getEnvironment(); String defaultSchema = env.getProperty("db.user"); 

Tenga en cuenta también que EL permite esto (valores predeterminados y sustitución recursiva profunda):

 @Value('${db.user:testdb}') private String dbUserName;  

Ver también:

  • Agregar un directorio a tomcat classpath
  • ¿Puedo crear una ruta de clases personalizada por aplicación en Tomcat
  • Cómo leer un archivo de propiedades fuera de mi contexto de aplicaciones web en Tomcat
  • Configure Tomcat para usar el archivo de propiedades para cargar información de conexión de BD
  • Debería configurar las propiedades de conexión de la base de datos en server.xml o context.xml
  • Externalizar la configuración de Tomcat

NOTA: al extender el directorio classpath to live, también permitiste externilizar cualquier otra configuración , como logging, auth, atc. Externilizo logback.xml de tal manera.

ACTUALIZACIÓN Tomcat 8 cambia la syntax de los elementos y , la parte correspondiente ahora se ve así:

     

Puede intentar colocar su configuración (archivo de propiedades) en Apache Tomcat \ lib en el archivo JAR y eliminarlo de la aplicación web. Cuando el cargador de clases de Tomcat no encuentre tu configuración en la aplicación web, intentará encontrarla en el directorio “lib”. Entonces puede externalizar su configuración simplemente moviendo la configuración a lib global (se comparte entre otras aplicaciones web).

Acabo de agregar un setenv.bat o setenv.sh en la carpeta bin de tomcat. Establezca la variable classpath como

 set CLASSPATH=my-propery-folder