que entre diferencia java jsp java-ee

java - entre - que es un jar



¿Puedo usar un único archivo war en múltiples entornos? ¿Debería? (8)

Tengo una aplicación web Java en mi trabajo y me gustaría simplificar la implementación en nuestros entornos DEV, QA y PROD.

La aplicación lee en una serie de propiedades al inicio, y los archivos de propiedades son diferentes para dev, qa y prod. Cada vez que deseo implementar en un entorno determinado, dejo caer el archivo de propiedades específicas del entorno en la carpeta de mi aplicación, genero la guerra y luego lo despliegue en uno de los tres servidores tomcat 5.5.

Lo que me gustaría hacer es tener un solo .war que tenga las propiedades para todos los entornos, y hacer que la aplicación interrogue al servidor web durante el proceso de inicio para averiguar en qué entorno se encuentra la aplicación y, por lo tanto, qué propiedades cargar. ¿Hay una manera fácil (o, en su defecto, una forma estándar) para hacer eso?


Absolutamente una sola GUERRA es la mejor manera de hacerlo. Establezca los recursos utilizando los mismos nombres JNDI en cada entorno, y si necesita detectar en qué entorno se encuentra con fines de lógica comercial, use una propiedad del sistema en el inicio de Tomcat.


Creo que un solo archivo war es una buena forma de hacerlo, porque es bueno tener la confianza de que el binario que probó en DEV es exactamente el mismo que en Production. La forma en que lo hacemos, mantenemos las configuraciones en un archivo de propiedades separado, fuera de la guerra, pero en la ruta de clase del servidor de la aplicación.

Si desea mantener todas las propiedades dentro de la guerra (lo que facilita la implementación, porque entonces no tiene que implementar un archivo de propiedades), puede mantener un archivo de propiedades único en la ruta de clase que identifica el tipo de entorno del servidor. y use eso para valores clave en el archivo de propiedades dentro de su archivo .war. El archivo de propiedades externas también puede ser una buena opción, tal vez algunas configuraciones de alto nivel que no cambian demasiado y se utilizan en varios archivos war.


Establezca un Systemproperty al inicio que señale la ubicación de su archivo de propiedades, y luego en su aplicación ingrese esta propiedad y cargue su configuración. Otra cosa que hago es tener dos archivos de propiedades, algo como default.properties y external.properties. Contienen las mismas propiedades, pero default.properties contiene el valor predeterminado (funciona la mayoría de las configuraciones de tiempo), este archivo entra en la guerra. Entonces si despliegas a un env. busca las propiedades externas. Si se encuentra que se utiliza, si no, se restituye a las propiedades predeterminadas. Esto proporciona una buena manera de anular las propiedades si es necesario, pero también tiene una configuración predeterminada. Esto funciona en muchas de mis implementaciones, pero puede que no en su escenario.


Esto realmente depende de para qué estás usando esas propiedades.

Algunos (como el origen de datos, por ejemplo) se pueden configurar en el contenedor mismo ( Tomcat 5.5. Recursos JNDI , ver también la sección de fuentes JDBC).

Otros (específicos de la aplicación) pueden necesitar ser propiedades. En cuyo caso tus elecciones son:

  1. Agrupe las propiedades dentro del archivo WAR y cargue el subconjunto apropiado en función de algún conmutador externo (ya sea una variable de entorno o una propiedad JVM)
  2. Configure un proceso de implementación en cada uno de sus servidores donde se desempaqueta la guerra y se copia un archivo de propiedades (ubicado en una ubicación predefinida en ese servidor y específico de ese servidor) en WEB-INF/classes (u otro lugar apropiado).

En cuanto a "es esto un objetivo deseable", sí, creo que sí. Tener una única GUERRA para probar en QA / puesta en escena y luego implementarla en producción corta un paso intermedio y deja menos posibilidades de errores.

Actualización (basada en comentarios):

El elemento n. ° 1 anterior hace referencia a una variable de entorno real (p. Ej., Algo que configura a través de SET ENV_NAME=QA en Windows o ENV_NAME=QA; export ENV_NAME en Linux). Puede leer su valor desde su código usando System.getenv() y cargar el archivo de propiedades apropiado:

String targetEnvironment = System.getenv("TARGET_ENV"); String resourceFileName = "/WEB-INF/configuration-" + targetEnvironment + ".properties"; InputStream is = getServletContext().getResourceAsStream(resourceFileName); Properties configuration = new Properties(); configuration.load(is);

Pero sí, en su lugar puede definir un valor escalar a través de JNDI ( consulte Entradas de entorno en Tomcat doc ) en su lugar:

<Context ...> <Environment name="TARGET_ENV" value="DEV" type="java.lang.String" override="false"/> </Context>

y léelo en tu aplicación a través de

Context context = (Context) InitialContext().lookup("java:comp/env"); String targetEnvironment = (String) context.lookup("TARGET_ENV"); // the rest is the same as above

La cuestión es que si va a utilizar JNDI de todos modos, también puede renunciar a los archivos de propiedad y configurar todo a través de JNDI. Sus fuentes de datos estarán disponibles para usted, ya que los recursos reales y las propiedades básicas seguirán siendo escalares (aunque serán de tipo seguro).

En última instancia, depende de usted decidir qué camino es mejor para sus necesidades específicas; Ambos tienen pros y contras.


Lo que usted hace es un accidente esperando a suceder ... Un día una guerra de DEV terminará en el servidor de PROD, y por alguna ley superior a todas las leyes de la naturaleza, ese problema se detectará a las 2 AM. No puedo explicar por qué este es el caso, pero algún día eso sucederá. Entonces, una guerra es en mi opinión definitivamente una buena idea.

Puede establecer una propiedad del sistema en las respectivas JVM (-Dcom.yourdomain.configpath = / where / you / store / configfiles) y recuperar esta propiedad con

String value = System.getProperty("com.yourdomain.configpath", "defaultvalue_if_any");

El valor predeterminado podría apuntar en algún lugar dentro de la guerra (WEB-INF / ...), o si no hay ningún valor predeterminado, se utilizará para hacer un poco de ruido de registro durante la carga para advertir de un error de configuración. También tenga en cuenta que esta técnica no depende de la plataforma, por lo que su máquina dev puede ser una caja de Windows y el servidor una máquina Linux, puede hacer frente a ambos. Normalmente creamos un subdirectorio por aplicación en este configpath, ya que varias aplicaciones usan este sistema en un servidor, y queremos mantener las cosas ordenadas.

Como una ventaja adicional, no se arriesga a destruir los archivos de propiedad ajustados manualmente en un servidor PROD de esta manera. Simplemente no olvide incluir la ruta donde se almacenan los archivos en un escenario de respaldo.


Prefiero el enfoque EAR o WAR. Hay algo que se vuelve a asegurar ya menudo se requiere desde el punto de vista de la seguridad acerca de tomar exactamente el mismo EAR que se acaba de probar y moverlo directamente al siguiente estado (prueba> Producción).

También hay muchas opciones además de los archivos de propiedades proporcionados por el contenedor. A menudo, el contenedor tiene una interfaz de usuario agradable para mantener esos valores y recursos cuando estás muerto y desaparecido.

Hay innumerables ejemplos de uso de ResourceBundle respaldado por una base de datos.

Por ejemplo, el marco Spring tiene varios mecanismos para que eso suceda sin mucho esfuerzo. Comenzando con PropertyPlaceholderConfigurer


Probablemente, la forma más simple sería configurar una variable de entorno que difiera entre los servicios de la aplicación y utilizarla para determinar qué archivo de propiedades leer.

Otra posibilidad sería almacenar las propiedades en una base de datos y usar una fuente de datos que existe bajo un nombre JNDI estándar, pero apunta a un lugar diferente en los diversos entornos.


Una compilación única (guerra) es ciertamente el enfoque correcto. Sin embargo, cuando se trata de una configuración específica del entorno, la mejor manera de hacerlo es garantizar que todos los archivos .properties de configuración no se envíen a todos los entornos. por ejemplo, los archivos de propiedades PROD deben copiarse a DEV o UAT. Los perfiles de resorte también deben evitarse ya que conducen a una administración de configuración intrincada.