Introducción
Maven es una gran herramienta que permite construir aplicaciones complejas y portables solo definiendo configuraciones dentro de un archivo POM, de este modo se remueven todas las referencias al sistema de archivos. El problema es que la portabilidad de una aplicación se vuelve compleja cuando las configuraciones de una aplicación cambian dependiendo del entorno en el que se despliegan.
Para resolver esto en Maven 2 se introdujo el concepto de perfiles, estos modifican el archivo POM en tiempo de compilación dependiendo del entorno, de este modo es posible tener diferentes valores para las configuraciones dependiendo del entorno.
Por ejemplo, pensemos en una aplicación que será desplegada en diferentes entornos: local, dev, qa y prod. Cada uno de los entornos tendrá configuraciones diferentes, ya que la base de datos que se utilizará en producción no será la misma que se utilizará en dev.
A través del uso de perfiles seremos capaces de modificar las configuraciones que utilizará nuestra aplicación al momento de compilarla.
Tipos de perfiles
- Por proyecto
- Es definido en el pom.xml
- Por usuario
- Es definido en el archivo settings.xml (El archivo se ubica en %USER_HOME%/.m2/settings.xml)
- Global
- Es definido en el archivo settings.xml global(El archivo se ubica en ${maven.home}/conf/settings.xml)
- Utilizando un descriptor (No soportado en Maven 3)
¿Cómo activar un perfil?
Un perfil se puede activar del siguiente modo:
- De forma explicita
- Utilizando Maven settings
- Basados en variables de entorno
- configuraciones en el sistema operativo
En este post se utilizará la linea de comandos para activar los perfiles, para esto se debe utilizar la opción -P seguida del nombre del perfil que se desea activar.
mvn clean install -Pdev
Creando una aplicación con diferentes perfiles
Para este ejemplo se definirán los perfiles dentro del proyecto utilizando el archivo pom.xml. La aplicación que se creará contendrá 2 perfiles dev y prod.
Paso 1: Crear los archivos de propiedades
El primer paso será crear 2 archivos properties con las configuraciones correspondientes a su entorno y colocarlos en el folder src/main/resources/.
dev.properties
db.url=jdbc:mysql://localhost:3306/db_dev db.user=root db.password=root
prod.properties
db.url=jdbc:mysql://dns.rds.hostinprod.com:3306/db_prod db.user=dbuserinprod db.password=Compl1cat3dP4ssw0rd
Paso 2: Definir los perfiles en el pom.xml
Una vez que se cuenta con los 2 archivos de configuración, es necesario definir los perfiles en el pom.xml.
<profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <delete file="${project.build.outputDirectory}/environment.properties" /> <copy file="src/main/resources/dev.properties" tofile="${project.build.outputDirectory}/environment.properties" /> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>prod</id> <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <delete file="${project.build.outputDirectory}/environment.properties" /> <copy file="src/main/resources/prod.properties" tofile="${project.build.outputDirectory}/environment.properties" /> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
Puntos importantes:
- El id que se coloque en la etiqueta será el que se utilizará al momento de compilar para especificar que se desea utilizar ese perfil.
- La etiqueta se utiliza para especificar que en caso de que no se indique ningún perfil, el perfil por defecto será el que la contiene, en este ejemplo es dev.
- Las etiquetas definidas dentro de la etiqueta definen lo siguiente(Se tomará como ejemplo el perfil dev):
- En caso de que el perfil dev sea seleccionado, se borrará el archivo environment.properties en caso de existir y se copiará el archivo dev.properties con el nombre de environment.properties.
- El punto anterior nos permite que nuestra aplicación solo busque el archivo environment.properties ya que este se generará utilizando ya sea el prod.properties o dev.properties de acuerdo al perfil que se defina cuando se compile la aplicación.
- Solo se incluyó el maven-compiler-plugin para utilizar java 8.
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Paso 4: Leyendo las propiedades
En nuestra aplicación Java lo único que se debe hacer ahora es leer las propiedades que contenga el archivo environment.properties.
/** * */ package com.raidentrance.util; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * @author raidentrance * */ public class ConfigurationLoader { private static Properties propProducer; private static final Logger log = Logger.getLogger(ConfigurationLoader.class.getName()); public static Properties getProperties(String name) { log.info("Loading configuration"); ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (propProducer == null) { Properties properties = new Properties(); try (InputStream resourceStream = loader.getResourceAsStream(name)) { properties.load(resourceStream); } catch (IOException e) { log.log(Level.SEVERE, e.getMessage()); } propProducer = properties; } return propProducer; } }
Paso 5: Mostrando las propiedades en pantalla
Una vez realizadas las configuraciones anteriores, lo único que resta es leer e imprimir las propiedades.
/** * */ package com.raidentrance.util; import java.util.Properties; /** * @author maagapi * */ public class TestConfigurationLoader { public static void main(String[] args) { Properties properties = ConfigurationLoader.getProperties("environment.properties"); System.out.println(properties); } }
Paso 5: Ejecutando todo
Vamos a hacer 3 pruebas para ejecutar la aplicación:
Prueba 1: Ejecutar el comando mvn clean install y ejecutar la aplicación.
Salida 1: {db.password=root, db.user=root, db.url=jdbc:mysql://localhost:3306/db_dev}
Prueba 2: Ejecutar el comando mvn clean install -Pdev y ejecutar la aplicación.
Salida 1:{db.password=root, db.user=root, db.url=jdbc:mysql://localhost:3306/db_dev}
Prueba 3: Ejecutar el comando mvn clean install -Pprod y ejecutar la aplicación.
Salida 3:{db.password=Compl1cat3dP4ssw0rd, db.user=dbuserinprod, db.url=jdbc:mysql://dns.rds.hostinprod.com:3306/db_prod}
Puedes encontrar el código completo del ejemplo en el siguiente enlace: https://github.com/raidentrance/profiles-app
Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com