Perfiles en Maven

Última actualización: 22/04/2021

maven

Durante el desarrollo de aplicaciones que van a ser utilizadas en distintos entornos (desarrollo, testing, producción, etc.), solemos encontrarnos con el problema de adaptar la aplicación a cada uno de ellos. Esto sucede con los ficheros de configuración, por ejemplo los parámetros utilizados para la conexión a la base de datos. También es posible que necesitemos incluir librerías distintas en función de la versión de Java o incluso el sistema operativo que estamos utilizando.

Apache Maven nos ayuda a solucionar esta problemática de forma elegante mediante el uso de perfiles. Un perfil es una configuración de Maven que solo queremos aplicar en determinadas circunstancias, ya sea especificando el perfil a utilizar o bien de forma automática según ciertas condiciones, como por ejemplo la versión del sistema operativo. Los perfiles pueden ser definidos para un proyecto concreto en su pom.xml o, de forma más general, en el fichero settings.xml de Maven.

En este breve tutorial veremos cómo utilizar distintas variables y ficheros de configuración seleccionables según el perfil que indiquemos. Otro ejemplo del uso de perfiles se encuentra en el tutorial Testing en WildFly con Arquillian perteneciente a mi curso de Jakarta EE.

El problema a resolver

Supongamos que tenemos un proyecto Maven consistente en una aplicación web en el que utilizamos dos ficheros de configuración: el del sistema de logs log4j y otro denominado db.properties con la cadena de conexión y las credenciales de la base de datos. Es habitual que un proyecto de este tipo deba ser desplegado en al menos tres entornos de explotación diferentes: el equipo de cada desarrollador, un servidor de pruebas y el servidor de producción final. Para simplificar el tutorial, vamos a considerar un entorno de desarrollo y otro de pruebas. El objetivo es utilizar una base de datos y un nivel de log distinto en cada uno de ellos.

Veamos dos posibles formas de afrontar esta situación para que podamos elegir la solución que más nos convenga.

Definir las variables en el pom.xml

Con esta estrategia, definimos en el pom.xml para cada perfil el valor que queremos darle a cada variable. De este modo, centralizamos en un único fichero los parámetros que dependen del entorno / perfil.

Seguimos los siguientes pasos.

  1. Crear la sección profiles con los dos perfiles. No vamos a declarar ninguna condición de activación automática, aunque podemos configurar uno como el predeterminado (activeByDefault). Dentro de cada perfil, se definen las variables y sus valores.
    <profiles>
    		<profile>
    			<id>desarrollo</id>
    			<!-- <activation> <activeByDefault>true</activeByDefault> </activation> -->
    			<properties>
    				<log.level>DEBUG</log.level>
    				<db.url>jdbc:mysql://localhost:3306/profiles</db.url>
    				<db.user>dev</db.user>
    				<db.password>devpassword</db.password>
    			</properties>
    		</profile>
    		<profile>
    			<id>pruebas</id>
    			<properties>
    				<log.level>INFO</log.level>
    				<db.url>jdbc:mysql://192.168.1.30:3306/profiles</db.url>
    				<db.user>pro</db.user>
    				<db.password>45fgU23</db.password>
    			</properties>
    		</profile>
    	</profiles>
    

    Nota. ¡Mucho cuidado! Hay que evitar versionar y\o distribuir datos de configuración sensibles tales como contraseñas. En el ejemplo estoy asumiendo que el entorno de pruebas no hay nada especialmente delicado.

  2. Usamos estas variables en los ficheros donde queremos que sean reemplazadas.
    /src/main/resources/log4j.xml

    <root>
       <priority value="${log.level}" />
       <appender-ref ref="console" />
       <appender-ref ref="file" />
    </root>
    

    /src/main/resources/db.properties

    driver=com.mysql.jdbc.Driver
    db.url = ${db.url}
    db.user = ${db.user}
    db.password = ${db.password}
    

    Si las variables a sustituir están en el fichero application.properties de Spring Boot, delimitamos con dos @ sus nombres.

    spring.datasource.username = @db.user@
    
  3. Activamos el filtrado de recursos para que Maven cambie las variables.
    <build>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>
    
  4. Al ejecutar una orden, debemos indicar los perfiles que queremos usar con el parámetro -P y separados por comas. Si no lo hacemos y no hay un perfil predeterminado, no se aplica ninguno.

    mvn clean package -P desarrollo
    

Un fichero para cada entorno

Otra alternativa consiste en tener un fichero de configuración distinto por cada entorno. Esto es, tendremos un db.properties y log4j.xml para desarrollo y otro db.properties y log4j.xml para pruebas. Toda la configuración estará en los ficheros correspondientes y no en el pom.xml.

Seguimos los siguientes pasos.

  1. Se organizan los ficheros de configuración en directorios según entornos/perfiles y fuera del /src/main/resources para evitar tener que hacer configuraciones adicionales de ensamblado. Siguiendo con nuestro ejemplo, tendríamos la siguiente estructura.

  2. En el pom.xml definimos los perfiles indicando para cada uno en una variable la carpeta en la que se encuentran los ficheros que serán incluidos en el artefacto final si se selecciona el perfil.
    <profiles>
    		<profile>
    			<id>desarrollo</id>
    			<!-- <activation> <activeByDefault>true</activeByDefault> </activation> -->
    			<properties>
    				<profile.dir>src/main/profiles/desarrollo</profile.dir>				
    			</properties>
    		</profile>
    		<profile>
    			<id>pruebas</id>
    			<properties>
    				<profile.dir>src/main/profiles/pruebas</profile.dir>				
    			</properties>
    		</profile>
    	</profiles>
    
  3. Indicamos que los ficheros ubicados en la ruta definida en el perfil deben copiarse al artefacto que genere Maven. Además, no podemos olvidarnos de los ficheros que ya tenemos en la carpeta estándar para los recursos /src/main/resources/.
        <build>       
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>${profile.dir}</directory>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    
  4. Al ejecutar una orden, debemos indicar los perfiles que queremos usar con el parámetro -P y separados por comas. Si no lo hacemos y no hay un perfil predeterminado, no se aplica ninguno.

    mvn clean package -P desarrollo
    

Perfiles en los IDE

Si bien los artefactos para desplegar generalmente se construyen de forma automatizada mediante scripts o sistemas de integración continua como Jenkins, trabajamos con los proyectos en un IDE. Si soporta Maven, debe permitirnos seleccionar los perfiles activos.

En IntelliJ, ya sea la versión Ultimate (de pago) o la Community (gratis), tenemos una vista (View->Tool Windows) llamada Maven. Muestra los perfiles existentes en el pom para que podamos marcar los que queremos tener activos. En raras ocasiones, el cambio no surte efecto, y es necesario pulsar el botón “Reload”.

Para configurar el perfil en Eclipse, hay que acceder a la sección Maven dentro de las propiedades del proyecto (botón derecho sobre el proyecto).
eclipse maven profiles

Más cómodo todavía: pulsando la combinación Control+Alt+P se mostrará la siguiente pantalla.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios .