2009-07-19 13 views
47

Tengo una aplicación web en Maven, con la estructura de directorio predeterminada. No hay problema allí. La estructura de directorios predeterminada tiene algunos archivos de propiedades que apuntan a mi base de datos localhost.Uso de Maven para entornos de despliegue múltiple (producción/desarrollo)

Actualmente puedo crear un script Ant para crear diferentes archivos de guerra - uno para la producción y otro para el desarrollo, el uso de estos comandos:

ant deploy-dev 
ant deploy-prod 
ant deploy-sit 
ant deploy-uat 

Así que, básicamente, se crea un archivo de la guerra y luego actualizar el archivo de la guerra por conectando el archivo de propiedades

¿Hay algo así en maven (se crean diferentes guerras según la configuración)?

si es así, ¿cómo hago eso?

Traté mvn war pero simplemente crea una guerra

+0

Es posible configurar el plugin Maven guerra con múltiples ejecuciones y clasificadores asociados, esto produce varios archivos de guerra de una sola ejecución cada denominarse adecuadamente. Veo http://stackoverflow.com/questions/3866784/release-different-configurations-with-maven – chrisinmtown

Respuesta

64

La mejor práctica FYI es no tiene que reconstruir su artefacto para diferentes entornos, ya que eso no conduce a nuevas versiones, y otras cosas podrían cambiar al reconstruir. Es decir. usar el filtrado de recursos, como se sugirió anteriormente, solo funciona cuando reconstruye su proyecto.

Cuando se gradúa un artefacto de dev a prueba o prueba de aceptación a producción - usted no necesita querer reconstruir.

Lo que se quiere hacer, es en realidad tener su configuración dinámica, en función de las variables en tiempo de ejecución. Es decir. diferentes configuraciones de resorte o archivos de propiedades para diferentes ambientes por ejemplo:

db-dev.properties 
db-test.properties 
db-prod.properties 

A continuación, se puede cambiar entre estas configuraciones utilizando las variables de tiempo de ejecución y la primavera de PropertyPlaceholderConfigurer.

Usted puede también utilizar realmente diferentes archivos de configuración de la primavera, así, como lo he hecho en el pasado, para configuraciones más complejas.

También sugiero que salga de su configuración 'por defecto' como la producción - de modo que si se implementa en la producción, que no tiene que preocuparse si se olvida de establecer la variable de entorno.

+1

Estoy de acuerdo en no tener que reconstruir el artefacto para pasar del desarrollo a la producción. ¿Cómo hace que la primavera cargue diferentes contextos en el tiempo de ejecución en función de una variable de tiempo de ejecución, por ejemplo, una propiedad del sistema? – mdma

+5

Dado que esta pregunta aparece cerca de la parte superior de los resultados de búsqueda para separar los entornos de desarrollo y desarrollo, vale la pena señalar que la propiedad '' en Spring 3.1 ([anuncio relevante] (http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/)) permite una carga condicional muy simple de beans en función de una variable de entorno. –

+5

Esto es una práctica que no será útil cuando construyas artefactos para distribución pública y en tu jar se guardarán credenciales para la base de datos de producción. Así que de nuevo, necesitas construir proyectos separados y ponerlos en repositorios privados y públicos. – m1ld

4

Hay this article sobre él en Maven 2 usando build profiles. Parece que simplemente delega a la hormiga de todos modos a través del plugin antrun, por lo que incluso podrías salirte con la suya al volver a utilizar tus archivos build.xml existentes.

18

Si desea eliminar la hormiga de su proceso, consideraría usar perfiles de compilación con filtros.

En este escenario, conecte sus archivos de propiedades a la estructura del árbol src/main/resources. Entonces parametrizar el archivo de propiedades con las propiedades del filtro como este:

jdbc.url=${filtered.jdbc.property} 

entonces dentro de src/main/filtros crear archivos de filtro basados ​​en perfiles. lo que podría tener dev-filters.properties sit-filters.properties, etc. Estos contener:

filtered.jdbc.property=jdbc url here 

A continuación, crear perfiles de configuración para cada región en la que se establece una env propiedad que apunta a la región en particular su edificio. A continuación, puede configurar el filtro de recursos para usar ${env}-filters.properties para cada compilación. Además, puede configurar el plugin war para agregar la propiedad env a su artefacto, de modo que realmente almacene 4 artefactos diferentes en su repositorio bajo un clasificador diferente.

Luego, simplemente crea la aplicación con cada perfil. Tienes que llamar a la compilación para cada perfil, pero funciona bien.

Ejemplo de algunos ajustes en el POM:

<build> 
    <filters> 
    <filter>src/main/filters/filter-${env}-application.properties</filter> 
    </filters> 
    <resources> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>true</filtering> 
    </resource> 
    </resources> 
    <plugins> 
    <plugin> 
     <artifactId>maven-war-plugin</artifactId> 
     <version>2.1-beta-1</version> 
     <executions> 
     <execution> 
      <phase>package</phase> 
      <goals> 
      <goal>war</goal> 
      </goals> 
      <configuration> 
      <classifier>${env}</classifier> 
      </configuration> 
     </execution> 
     </executions> 
    </plugin> 
    </plugins> 
</build> 

<profiles> 
    <profile> 
    <id>LOCAL</id> 
    <activation> 
     <activeByDefault>true</activeByDefault> 
    </activation> 
    <properties> 
     <env>LOCAL</env> 
    </properties> 
    </profile> 
    <profile> 
    <id>DEV</id> 
    <properties> 
     <env>DEV</env> 
    </properties> 
    </profile> 
    <profile> 
    <id>UAT</id> 
    <properties> 
     <env>UAT</env> 
    </properties> 
    </profile> 
    <profile> 
    <id>PROD</id> 
    <properties> 
     <env>PROD</env> 
    </properties> 
    </profile> 
</profiles> 

También, apoyos a este blog post que es donde encontré originalmente los pasos para lograr esto.

+0

Esto funciona, pero creo que es mucho mejor tener un artefacto desplegar todas partes, como sugiere Antony Stubbs. En proyectos de software más grandes, tendrá muchos entornos en los que implementará las cosas (producción, pruebas, entorno de desarrollo, cada máquina de desarrollador ), y crear diferentes WAR para cada uno de ellos es un problema. –

+0

Bueno, depende. Construir una guerra diferente para cada región es simple usando Hudson. Solo copio la configuración, creo una nueva construcción nocturna y cambio el perfil con el que se construye. Estas compilaciones se implementan en Nexus, lo que significa que si alguien lo quiere, pueden extraer de Nexus o mirar a Hudson para ver qué hace. Si no está usando un sistema de CI, puedo ver cómo podría ser un problema. El riesgo es muy bajo, ya que todo lo que estoy cambiando son archivos de propiedades ...Todo lo demás es un contenedor que ha sido probado en un proyecto Maven diferente. –

6

he manejado esto utilizando PropertyPlaceholderConfigurer de primavera y que incluyen archivos de propiedades en la ruta de clase y uno en el sistema de archivos:

<context:property-placeholder 
    location="classpath*:META-INF/spring/*.properties,file:myapp*.properties"/> 

Si hay un archivo de miaplicacion * .properties en el directorio actual cuando se inicia la aplicación (o pruebas se ejecutan etc.) se anulará propiedades de los archivos de horno en la guerra/oído/lo que sea.

57

Prefiero usar perfiles maven para esta situación. por ejemplo tenemos la estructura de directorios:

 
src/main/resources 
| 
+- local 
| | 
| `- specific.properties 
+- dev 
    | 
    `- specific.properties 

En pom.xml definir dos perfiles:

<profiles> 
    <profile> 
     <id>local</id> 
     <activation> 
      <activeByDefault>true</activeByDefault> 
     </activation> 
     <build> 
      <resources> 
       <resource> 
        <directory>src/main/resources/local</directory> 
       </resource> 
      </resources> 
     </build> 
    </profile> 
    <profile> 
     <id>dev</id> 
     <build> 
      <resources> 
       <resource> 
        <directory>src/main/resources/dev</directory> 
       </resource> 
      </resources> 
     </build> 
    </profile> 
</profiles> 

En ese caso, no necesita actualizar cada pom.xml tiempo para los nuevos archivos. En IDE, simplemente cambie de perfil o use -P flag desde la línea de comando.

UPD: ¿qué hacer si algunas propiedades son las mismas para las configuraciones? Haga la configuración de la siguiente manera:

<profiles> 
    <profile> 
     <id>local</id> 
     <activation> 
      <activeByDefault>true</activeByDefault> 
     </activation> 
     <build> 
      <resources> 
       <resource> 
        <directory>src/main/resources</directory> 
       </resource> 
       <resource> 
        <directory>src/main/config/local</directory> 
       </resource> 
      </resources> 
     </build> 
    </profile> 
    <profile> 
     <id>dev</id> 
     <build> 
      <resources> 
       <resource> 
        <directory>src/main/resources</directory> 
       </resource> 
       <resource> 
        <directory>src/main/config/dev</directory> 
       </resource> 
      </resources> 
     </build> 
    </profile> 
</profiles> 

parte común se almacena en src/main/resources y otras configuraciones estarán en carpetas correspondientes en el directorio config.

+3

¡Gran ejemplo, exactamente lo que estaba buscando mientras trato de aprender maven! Gracias –

+0

funcionó perfecto. gracias – austin

+3

El plugin de recursos de Maven comprueba la marca de tiempo contra los archivos en 'target /' y solo copia si el archivo es más nuevo. Siempre ejecute 'mvn clean' cuando cambie de perfil o establezca' true 'para el complemento de recursos maven. – bcoughlan

Cuestiones relacionadas