Maven. Плагины для сборки простых проектов

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

Содержание:


Конфигурирование компилятора.

Maven Compiler plugin

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

В простейшем случае плагин позволяет задать версию java для которой написан код и версию java для компилирования.
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>2.5.1</version>
  <configuration>
    <source>1.5</source>
    <target>1.6</target>
  </configuration>
</plugin>
         
Из более серьезных возможностей, плагин позволяет указать путь к компилятору, запустить компилирование в отдельной JVM, задавать аргументы компилирования и даже выполнить компилирование не-java компилятором.

Создание jar-файла и файла манифеста.

Maven JAR Plugin

Этот плагин позволяет убить сразу нескольких зайцев: создать манифест и jar-файл, и описать дополнительные ресурсы, которые необходимо включить в jar-файл.

Дополнительные ресурсы, включаемые в jar, описываются тегами <include> и <exclude>(для включения и исключения соответственно):
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <includes>
      <include>**/service/*</include>
    </includes>
    <excludes>
      <exclude>**/*.png</exclude>
    </excludes>
  </configuration>
</plugin>
Для создания манифеста плагин предоставляет достаточно много вариантов. Со всеми возможностями лучше ознакомиться на официальном сайте. Здесь я приведу лишь самые распространенные (на мой взгляд и опыт) из них.

Первое, самое простое решение - указать уже существующий файл манифеста:
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
    </archive>
  </configuration>
</plugin>


Второй - описать манифест в настройках плагина. Для наглядности сразу приведу простой пример конфигурации плагина:
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-jar-plugin</artifactId>
   <version>2.4</version>
   <configuration>
      <archive>
         <index>true</index>
         <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>ru.dokwork.App</mainClass>
         </manifest>
      </archive>
   </configuration>
</plugin>
Параметр <addClasspath/> включает добавление classpath-а в манифест.
<classpathPrefix/> позволяет дописывать префикс перед каждым ресурсом. Удобно, если вы размещаете ваши зависимости в отдельной папке, на пример lib.
<mainClass/> очевидно позволяет указать главный исполняемый класс.

Пример результата:
Class-Path: lib/plexus-utils-1.1.jar


Помимо автоматической генерации classpath-а, можно описать его вручную:
<plugin>
   <artifactId>maven-war-plugin</artifactId>
   <configuration>
     <archive>
       <manifest>
         <addClasspath>true</addClasspath>
         <classpathLayoutType>custom</classpathLayoutType>
         <customClasspathLayout>
            WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}.$${artifact.extension}
         </customClasspathLayout>
       </manifest>
     </archive>
   </configuration>
</plugin>
В данном примере classpath генерируется по маске, в которой значения $${artifact.groupIdPath}, $${artifact.artifactId} и $${artifact.version} заменяются на соответствующие значения параметров зависимостей, описанных в блоке <dependencies>.

Пример результата:
Class-Path: WEB-INF/lib/org/codehaus/plexus/plexus-utils-1.1.jar
Или сгенерировать в соответствии с традициями maven:
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-jar-plugin</artifactId>
   <version>2.4</version>
   <configuration>
      <archive>
         <index>true</index>
         <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <classpathLayoutType>repository</classpathLayoutType>
         </manifest>
      </archive>
   </configuration>
</plugin>
Пример результата:
Class-Path: Class-Path: lib/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar

Копирование зависимостей.

Maven Dependency Plugin

Плагин позволяет копировать зависимости, описанные в pom.xml в указанную директорию. Плагин обладает множеством настроек и тонкостей использования, изучить которые всегда можно на официальном сайте. Здесь я сосредоточусь только на простом примере.
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-dependency-plugin</artifactId>
   <version>2.5.1</version>
   <executions>
      <execution>
         <id>copy-dependencies</id>
         <phase>package</phase>
         <goals>
            <goal>copy-dependencies</goal>
         </goals>
         <configuration>
            <outputDirectory>${project.build.directory}/${lib.dir}</outputDirectory>
            <overWriteReleases>false</overWriteReleases>
            <overWriteSnapshots>false</overWriteSnapshots>
            <overWriteIfNewer>true</overWriteIfNewer>
            <useRepositoryLayout>false</useRepositoryLayout>
         </configuration>
      </execution>
   </executions>
</plugin>
  • outputDirectory - указывает путь к директории, в которую будут скопированы зависимости;
  • overWriteReleases - true, если необходимо перезаписывать зависимости при релизе;
  • overWriteSnapshots - true, если необходимо перезаписывать зависимости при создании снапшота;
  • overWriteIfNewer - true, если необходимо перезаписывать зависимости в случае, если они изменились с прошлого раза;
  • useRepositoryLayout - значение true позволит сохранить оригинальную структура каталога.

Значения по умолчанию для overWriteReleases и overWriteSnapshots - false, для overWriteIfNewer - true.

Копирование ресурсов.

Maven Resources Plugin

Помимо копирования ресурсов во время сборки проекта, я пользовался этим плагином на стадии инсталляции, для копирования проекта на сервер.

Конфигурирование плагина достаточно простое, интуитивное и в то же время гибкое:
<plugin>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <executions>
      <execution>
         <id>copy-resources</id>
         <!-- here the phase you need -->
         <phase>validate</phase>
         <goals>
            <goal>copy-resources</goal>
         </goals>
         <configuration>
            <outputDirectory>${basedir}/target/extra-resources</outputDirectory>
            <resources>
               <resource>
                  <directory>src/non-packaged-resources</directory>
                  <filtering>false</filtering>
                  <includes>
                     <include>example.jar</include>
                  </includes>
                  <excludes>
                     <exclude>temp.txt</exclude>
                  </excludes>
               </resource>
            </resources>
         </configuration>
      </execution>
   </executions>
</plugin>
<outputDirectory> описывает целевую директорию, в которую будет происходить копирование. В блоке <resources> перечисляются объекты для копирования. Синтаксис перечисления объектов для включения/исключения аналогичен используемому в Maven JAR Plugin.

Параметр <filtering> позволяет творить всякие чудеса, почитать о которых можно здесь.

Вкратце, если у вас есть некоторый текстовый ресурс hello.txt с содержимым вида Hello ${name}, то в результате копирования этого ресурса с флагом filtering = true, в созданной копии значение ${name} будет заменено названием проекта указанным в pom.xml.

Авторы рекомендуют не использовать filtering с бинарными файлами вроде изображений.



Возможно со временем список перечисленных плагинов вырастет, а пока Maven Plugins Вам в помощь.

2 комментария:

ares4322 комментирует...

Спасибо!
Час бился над тем, как исключить ресурсы из итоговой jar. А по твоему примеру все сразу заработало.

Vladimir Popov комментирует...

рад что пригодилось!