Использование профилей в Maven

7 апреля 2011 г.

В maven существует возможность изменять настройки проекта в зависимости от окружения, это реализовано через профили проекта. Профиль содержит в себе настройки, которые будут добавлены к основным настройкам, или, наоборот, заместят их.

<project>
 ...
 <profiles>
  <profile>
   <id>test</id>
   <activation>...</activation>
   <build>...</build>
   <modules>...</modules>
   <repositories>...</repositories>
   <pluginRepositories>...</pluginRepositories>
   <dependencies>...</dependencies>
   <reporting>...</reporting>
   <dependencyManagement>...</dependencyManagement>
   <distributionManagement>...</distributionManagement>
  </profile>
 </profiles>
</project>

Профиль можно активировать (включить) явно, указав в строке запуска мейвена имя профиля через опцию -P:

mvn -Pимя_профиля

Либо указав условия активации. Профиль будет активирован, если выполнилось хотя бы одно условие активации. Условием активации может быть наличие или значение определенной переменной окружения, версия JDK, версия или тип операционной системы, наличие или отсутствие определенного файла.

<project>
 ...
 <profiles>
  <profile>
   <id>test</id>
   <activation>
    <activeByDefault>false</activeByDefault>
    <jdk>1.5</jdk>
    <os>
     <name>Windows XP</name>
     <family>Windows</family>
     <arch>x86</arch>
     <version>5.1.2600</version>
    </os>
    <property>
     <name>mavenVersion</name>
     <value>2.0.3</value>
    </property>
    <file>
     <exists>${basedir}/file2.properties</exists>
     <missing>${basedir}/file1.properties</missing>
    </file>
   </activation>
   ...
  </profile>
 </profiles>
</project>

Например, у вас в проекте есть агрегирующий модуль с модулем интеграционных тестов и модулем selenium тестов, и вы, естественно, не хотите, чтобы тесты запускались на машинах разработчиков во время выполнения рутинной операции «компиляция — юнит-тесты – упаковка»:

mvn clean install.

Это пожелание можно реализовать с помощью мейвеновских профилей.
Изначальный pom.xml для агрегирующего модуля:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>habr</groupId>
 <artifactId>aggr</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>Profiles Demo - Top</name>
 
 <modules>
  <module>module1</module>
  <module>integration-tests</module>
  <module>selenium-tests</module>
 </modules> 
</project>

Результат запуска mvn clean install:
------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.859s]
Profiles Demo - Integration Tests ..................... SUCCESS [0.265s]
Profiles Demo - Selenium Tests ........................ SUCCESS [0.250s]
Profiles Demo - Top ................................... SUCCESS [1.172s]
------------------------------------------------------------------------

Выделяем интеграционные тесты в отдельный профиль с именем it:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>habr</groupId>
 <artifactId>aggr</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>Profiles Demo - Top</name>
 
 <modules>
  <module>module1</module>
  <module>selenium-tests</module>
 </modules>
 
 <profiles>
  <profile>
   <id>it</id>
   <modules>
    <module>integration-tests</module>
   </modules>   
  </profile>
 </profiles>  
</project>

Результат запуска mvn clean install
------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.828s]
Profiles Demo - Selenium Tests ........................ SUCCESS [0.282s]
Profiles Demo - Top ................................... SUCCESS [1.219s]
------------------------------------------------------------------------

Как видим, интеграционные тесты не были включены в процесс сборки. Чтобы включить их достаточно указать имя профиля it.

mvn clean install -Pit

------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.875s]
Profiles Demo - Selenium Tests ........................ SUCCESS [0.266s]
Profiles Demo - Integration Tests ..................... SUCCESS [0.266s]
Profiles Demo - Top ................................... SUCCESS [1.156s]
------------------------------------------------------------------------

Оп, интеграционные тесты снова с нами.

При указании профиля it, мейвен добавил (именно добавил, а не заместил всю конфигурацию проекта) модуль integration-tests в сборку. Аналогично можно сделать и с модулем Selenium тестов.

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>habr</groupId>
 <artifactId>aggr</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>Profiles Demo - Top</name>
 
 <modules>
  <module>module1</module>  
 </modules>
 
 <profiles>
  <profile>
   <id>it</id>
   <modules>
    <module>integration-tests</module>
   </modules>   
  </profile>  
  <profile>
   <id>selenium</id>
   <modules>
    <module>selenium-tests</module>
   </modules>   
  </profile>
 </profiles> 
 
</project>

Собрать всё вместе можно указав оба профиля mvn clean install -Pit -Pselenium:

------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.812s]
Profiles Demo - Integration Tests ..................... SUCCESS [0.312s]
Profiles Demo - Selenium Tests ........................ SUCCESS [0.250s]
Profiles Demo - Top ................................... SUCCESS [1.141s]
------------------------------------------------------------------------

С ног на голову

А теперь сделаем обратный процесс. Например, на моем проекте один модулей вытаскивает из репозитория сервер приложений, запакованный в виде jar файла, распаковывает его в определенную папку, вытаскивает артефакты проекта и закидывает их в папку сервера приложения, генерирует батники и конфиги для запуска всех этих плюшек и.т.п.
Нужно чтобы на машинах разработчиков этот модуль запускался без всякой магии, а на билд сервере, во время деплоя снепшота, наоборот не запускался.

Изначальный pom.xml выглядит так:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>habr</groupId>
 <artifactId>aggr</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>Profiles Demo - Top</name>
 
 <modules>
  <module>module1</module>
  <module>create-server</module>
 </modules>  
</project>

------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.875s]
Profiles Demo - Create Server ......................... SUCCESS [0.203s]
Profiles Demo - Top ................................... SUCCESS [1.250s]
------------------------------------------------------------------------

Меняем pom.xml, переселяем все модули в профиль по умолчанию default, добавляем в конфигурацию профиля секцию activation. А для сценария, когда не нужно делать сборку с сервером приложений, создаем профиль noserver, где указаны все модули, кроме сервера приложений.

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>habr</groupId>
 <artifactId>aggr</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>Profiles Demo - Top</name>
  
 <profiles>

  <profile>
   <id>default</id>
   <activation>
    <activeByDefault>true</activeByDefault>
   </activation>
    <modules>
     <module>module1</module>
     <module>create-server</module>
    </modules>
  </profile> 
   
  <profile>
   <id>noserver</id>
   <modules>
    <module>module1</module>
   </modules>   
  </profile>

 </profiles>   
</project>

Запускаем mvn clean install (сценарий на машине разработчика):
------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.891s]
Profiles Demo - Create Server ......................... SUCCESS [0.266s]
Profiles Demo - Top ................................... SUCCESS [1.188s]
------------------------------------------------------------------------

Видим, что собрались все модули вместе с сервером приложений.

А теперь запускаем maven с профилем noserver (сценарий для билд сервера)
mvn clean install –Pnoserver:
------------------------------------------------------------------------
Profiles Demo - Module1 ............................... SUCCESS [1.734s]
Profiles Demo - Top ................................... SUCCESS [1.234s]
------------------------------------------------------------------------

Как видим, модуль сервера не участвует в сборке.

Заключение

Аналогично можно управлять зависимостями, плагинами, репозиториями и т.п. Например, для MacOS можно делать сборку с одной версией графической библиотеки, а на Win с другой.
Чтобы не использовать имена профилей, можно на билд сервере установить глобальную переменную окружения, при наличии которой будет активироваться тот или иной профиль.

Ссылки

maven.apache.org/pom.html#Profiles

Теги: рубрика Программирование
  • Похожие статьи
  • Предыдущие из рубрики