-
Notifications
You must be signed in to change notification settings - Fork 56
Полезные плагины для maven
Для сборки Jar-файла необходимо использовать соответствующий плагин.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<compress>true</compress>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>a1s.client.App</mainClass>
</manifest>
</archive>
</configuration>
<version>2.4</version>
</plugin>
В данном случае загружается плагин для сборки в jar-файл и производятся настройки:
-
<addMavenDescriptor>false</addMavenDescriptor>
- отключает копированиеpom.xml
иpom.properties
вMETA-INF/maven
-
<compress>true</compress>
- использовать сжатие -
<addClasspath>true</addClasspath>
- добавить зависимости в classpath манифеста -
<classpathPrefix>libs/</classpathPrefix>
- путь к библиотекам зависимостей, которые добавляются в classpath -
<mainClass>a1s.client.App</mainClass>
- полное имя класса, в котором используется методmain
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
<version>2.5.1</version>
</plugin>
Данный плагин копирует файлы зависимостей в соответствующую директорию при сборке.
Данный плагин реализует цель copy-dependencies
, которая включается на этапе package
.
В качестве конфигурации передаётся директория для копирования файлов зависимостей (${project.build.directory}/libs
), в нашем случае это будет target/libs
.
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.8.v20121106</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>9090</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
Рассмотрим настраиваемые свойства:
-
scanIntervalSeconds
- интервал в секундах через который Jetty проверяет директории на изменения для редеплоя приложения -
connectors
- список подключений -
port
- настраивает порт, на котором будет запущен jetty
После подключения плагина стало возможным проводить развёртывание проекта с использованием команды mvn jetty:run
.
Номер build'а может быть важным инструментов для отслеживания регрессионных багов или поиске неисправленостей при долгосрочной поддержке системы. Поэтому хотелось бы иметь увеличивающийся автоматический счётчик build'ов.
В maven подобной функциональности можно достичь с помощью buildnumber-maven-plugin
из org.codehaus.mojo
.
Данный плагин позволяет реализовывать версионность билдов на основе:
- инкрементального счётчика
- даты (timestamp)
- версии из системы контроля версий
Данный плагин требует наличия секции с описанием параметров системы контроля версий, даже если используется инкрементальный счётчик или версия на основе времени, поэтому объявим fake'овый раздел <scm />
.
pom.xml
<scm>
<connection>scm:svn:http://127.0.0.1/svn/my-project</connection>
<developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection>
<tag>HEAD</tag>
<url>http://127.0.0.1/websvn/my-project</url>
</scm>
Теперь подкючим плагин для проставления номера build'а.
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<revisionOnScmFailure>1</revisionOnScmFailure>
<doCheck>true</doCheck>
<buildNumberPropertyName>buildNumber</buildNumberPropertyName>
<doUpdate>true</doUpdate>
<format>{0,number}</format>
<items>
<item>buildNumber</item>
</items>
</configuration>
</plugin>
Рассмотрим параметры более подробно:
-
<revisionOnScmFailure>1</revisionOnScmFailure>
- номер присваиваемой ревизии в случае, если доступ в систему контроля версий закончился ошибкой -
<buildNumberPropertyName>buildNumber</buildNumberPropertyName>
- наименование свойства, в котором будет сохранён номер build'а -
<format>{0,number}</format>
- формат номера build'а в текущем случае просто цифровое значение -
<items />
- генерируемые значения-
<item>buildNumber</item>
- название счётчика
-
соберём проект:
$ mvn clean install
...
[INFO] --- buildnumber-maven-plugin:1.1:create (default) @ testbuildnumber ---
[INFO] Storing buildNumber: 1 at timestamp: 1355932828379
...
$ ls
buildNumber.properties pom.xml src target
$ cat buildNumber.properties
#maven.buildNumber.plugin properties file
#Wed Dec 19 19:00:28 MSK 2012
buildNumber=1
в корне проекта был создан файл buildNumber.properties
, в котором и будет сохраняться версия build'а.
Если рассмотреть манифест jar-файла из предыдущего примера, то в нём не окажется версии сборки.
$ unzip -p target/testbuildnumber-1.0.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Built-By: wiz
Build-Jdk: 1.7.0
Created-By: Apache Maven 3.0.4
Main-Class: a1s.client.App
Archiver-Version: Plexus Archiver
Для добавления версии сборки в manifest необходимо добавить соответствующие настройки в плагин сборки jar-файла.
pom.xml (раздел configuration/archive
плагина maven-jar-plugin
)
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
полный текст подключения jar-плагина будет таким:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<compress>true</compress>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>a1s.client.App</mainClass>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
<version>2.4</version>
</plugin>
Соберём проект и просмотрим файл манифеста.
$ mvn clean install
...
$ unzip -p target/testbuildnumber-1.0.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Built-By: wiz
Build-Jdk: 1.7.0
Created-By: Apache Maven 3.0.4
Implementation-Build: 2
Main-Class: a1s.client.App
Archiver-Version: Plexus Archiver
Иногда может понадобиться добавлять номер build'а к имени файла. Реализуем нумерацию в виде 1.0.12345, где 1.0 - версия, а 12345 - номер build'а.
Для этого внесём изменение в формат номера build'а:
<format>${project.version}.{0,number}</format>
добавим элемент <finalName />
в раздел <build />
.
<finalName>${project.name}-${buildNumber}</finalName>
Соберём проект и посмотрим, что получилось:
$ mvn clean intall
$ ls target/
classes libs surefire surefire-reports testbuildnumber-1.0.4.jar test-classes
$ unzip -p target/testbuildnumber-1.0.4.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Built-By: wiz
Build-Jdk: 1.7.0
Created-By: Apache Maven 3.0.4
Implementation-Build: 1.0.4
Main-Class: a1s.client.App
Archiver-Version: Plexus Archiver
Как видно из вывода был собран jar-файл testbuildnumber-1.0.4.jar
с указанием номера версии и build'а в имени файла и в файле манифеста внутри jar-архива.
Добавим в качестве номера build'а текущую дату (в формате yyyy_MM_dd_HH_mm_ss ), для этого добавим следующую настройку:
<format>${project.version}.{0,date,yyyy_MM_dd_HH_mm_ss}</format>
Соберём проект:
$ mvn clean install
$ ls target/
classes libs surefire surefire-reports testbuildnumber-1.0.2012_12_19_19_48_51.jar test-classes
Возможно объединять текущий timestamp и инкрементальный buildnumber.
<format>${project.version}.{0,number}.{1,date,yyyyMMddHHmmss}</format>
<items>
<item>buildNumber0</item>
<item>timestamp</item>
</items>
$ mvn clean install
$ ls target/
classes libs surefire surefire-reports testbuildnumber-1.0.1.20121219201648.jar test-classes
Maven buildnumber plugin использует MessageFormat для обработки свойств, поэтому возможно форматировать свойства в соответствии с правилами.
Например,
- генерация текущей даты номера build'а
<format>{0,date,yyyyMMdd}</format>
- генерация текущей даты номера build'а
<format>{0,date,yyyyMMddHHiiss}</format>
Допустим необходимо сгенерировать 2 разных номера для названия JAR-файла и для свойства в манифесте.
Для этого необходимо разделить генерацию buildnumber'ов по разделам execution разделим buildnumber для имени файла и builddate для свойства в манифесте.
Изменим параметр задания свойства в манифесте:
<manifestEntries>
<Implementation-Build>${buildNumber} at ${buildDate}</Implementation-Build>
</manifestEntries>
и добавим генерацию 2-х buildnumber'ов:
<executions>
<execution>
<id>buildNumber</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<buildNumberPropertyName>buildNumber</buildNumberPropertyName>
<format>${project.version}.{0,number}</format>
<items>
<item>buildNumber0</item>
</items>
</configuration>
</execution>
<execution>
<id>buildDate</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<buildNumberPropertyName>buildDate</buildNumberPropertyName>
<format>{0,date,yyyy-MM-dd HH:mm:ss}</format>
<items>
<item>timestamp</item>
</items>
</configuration>
</execution>
</executions>
соберём проект
$ mvn clean install
$ ls target/
classes libs surefire surefire-reports testbuildnumber-1.0.4.jar test-classes
$ unzip -p target/testbuildnumber-1.0.4.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Built-By: wiz
Build-Jdk: 1.7.0
Created-By: Apache Maven 3.0.4
Implementation-Build: 1.0.4 at 2012-12-19 20:24:25
Main-Class: a1s.client.App
Archiver-Version: Plexus Archiver
в имя файла добавлен номер build'а, а в манифест полная строка с датой билда.
Кроме создания JAR-файла с зависимостями может понадобится создать архив со сборков приложения. Для этого понадобится maven-assembly plugin, который может создавать директорию со всеми ресурсами или архивы со сборкой приложения.
Создадим следующуй структуру директорий:
$ tree
.
├── bin
│ └── start.sh
├── dist
│ ├── app-0.0.1-SNAPSHOT.jar
│ └── libs
├── etc
│ └── app.properties
└── jni
Пройдёмся по директориям:
-
bin
основная директория, в которой будут скрипты для запуска приложения -
dist
- директория для jar-файлов-
libs
- директория с зависимостями
-
-
etc
- директория с настройками
Добавим в pom.xml использование maven-assembly-plugin. Добавим плагин последним в список плагинов.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptor>src/main/assembly/bin.xml</descriptor>
</configuration>
</plugin>
Само же описание сборки располагается в дескрипторе сборки по адресу src/main/assembly/bin.xml
.
Рассмотрим дескриптор сборки: bin.xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>
<formats>
<format>zip</format>
<format>dir</format>
</formats>
<fileSets>
<fileSet>
<directory>target/libs</directory>
<outputDirectory>dist/libs</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>target</directory>
<outputDirectory>dist</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/resources/bin</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>*.sh</include>
</includes>
<fileMode>0755</fileMode>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>src/main/resources/etc</directory>
<outputDirectory>etc</outputDirectory>
<includes>
<include>*</include>
</includes>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>src/main/resources/jni</directory>
<outputDirectory>jni</outputDirectory>
<includes>
<include>*.so</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Рассмотрим параметры подробнее:
-
<id>bin</id>
- идетификатор сборки -
<formats>
- описывает генерируемые форматы сборок (в нашем случае будет просто директория со сборкой и ZIP-файл). Можно указывать несколько форматов для сборки. -
<fileSets>
- описывает наборы файлов для сборки
Рассмотрим параметры fileset'ов на примере диреутории со скрптами запуска:
-
<directory>src/main/resources/bin</directory>
- директория откуда копируем -
<outputDirectory>bin</outputDirectory>
- директория куда копируем -
<includes><include>*.sh</include></includes>
- какие файлы копируем? -
<fileMode>0755</fileMode>
- устанавливаем атрибуты файла -
<filtered>true</filtered>
- использовать фильтрацию
Рассмотрим скрипт для запуска приложения: start.sh
#!/bin/bash
cd ..
export LD_LIBRARY_PATH="./jni/"
java -jar ./dist/${project.build.finalName}.jar
В качестве имени jar-файла для запуска используется параметр ${project.build.finalName}
, который будет заменён на реальное имя jar-файла.
Соберём проект
$ mvn clean install
После сборки в директории target появится директория по имени файла, в которой собрано приложение и zip-архив с приложением.
Может возникнуть ситуация, когда необходимо добавить дополнительные ресурсы в зависимости от профиля, тогда нам поможет component descriptors для maven assembly plugin.
Опишем компонент:
<?xml version="1.0" encoding="UTF-8"?>
<component xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2 http://maven.apache.org/xsd/component-1.1.2.xsd">
<fileSet>
<directory>src/main/resources/dump</directory>
<outputDirectory>dump</outputDirectory>
<includes>
<include>*.sql</include>
</includes>
</fileSet>
</component>
Теперь в файле дескриптор асборки можно подключить этот компонент, например, используя идентификатор профиля в названии:
<componentDescriptors>
<componentDescriptor>specific-${profile.id}.xml</componentDescriptor>
</componentDescriptors>
Для maven есть плагин для проверки версий зависимостей. pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.0</version>
</plugin>
$ mvn versions:display-dependency-updates
...
[INFO] The following dependencies in Dependencies are using the newest version:
[INFO] javax.servlet:jstl ............................................... 1.2
[INFO] joda-time:joda-time-jsptags .................................... 1.1.1
[INFO] junit:junit ..................................................... 4.11
[INFO] org.apache.tiles:tiles-core .................................... 3.0.1
[INFO] org.apache.tiles:tiles-jsp ..................................... 3.0.1
[INFO] org.eclipse.persistence:eclipselink ............................ 2.3.2
[INFO] org.eclipse.persistence:javax.persistence ...................... 2.0.3
[INFO] org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processor ...
[INFO] 2.3.2
[INFO] org.hibernate:hibernate-annotations ...................... 3.5.6-Final
[INFO] org.springframework:spring-aop ......................... 3.2.2.RELEASE
[INFO] org.springframework:spring-beans ....................... 3.2.2.RELEASE
[INFO] org.springframework:spring-context ..................... 3.2.2.RELEASE
[INFO] org.springframework:spring-core ........................ 3.2.2.RELEASE
[INFO] org.springframework:spring-jdbc ........................ 3.2.2.RELEASE
[INFO] org.springframework:spring-orm ......................... 3.2.2.RELEASE
[INFO] org.springframework:spring-test ........................ 3.2.2.RELEASE
[INFO] org.springframework:spring-tx .......................... 3.2.2.RELEASE
[INFO] org.springframework:spring-web ......................... 3.2.2.RELEASE
[INFO] org.springframework:spring-webmvc ...................... 3.2.2.RELEASE
[INFO] org.springframework.security:spring-security-config .... 3.1.3.RELEASE
[INFO] org.springframework.security:spring-security-core ...... 3.1.3.RELEASE
[INFO] org.springframework.security:spring-security-ldap ...... 3.1.3.RELEASE
[INFO] org.springframework.security:spring-security-taglibs ... 3.1.3.RELEASE
[INFO] org.springframework.security:spring-security-web ....... 3.1.3.RELEASE
[INFO] taglibs:standard ............................................... 1.1.2
[INFO]
[INFO] The following dependencies in Dependencies have newer versions:
[INFO] cglib:cglib ............................................. 2.2.2 -> 3.0
[INFO] ch.qos.logback:logback-access ........................ 1.0.9 -> 1.0.11
[INFO] ch.qos.logback:logback-classic ....................... 1.0.9 -> 1.0.11
[INFO] ch.qos.logback:logback-core .......................... 1.0.9 -> 1.0.11
[INFO] com.google.guava:guava ............................ 14.0-rc3 -> 14.0.1
[INFO] com.h2database:h2 ................................. 1.3.170 -> 1.3.171
[INFO] javax.servlet:servlet-api ......................... 2.5 -> 3.0-alpha-1
[INFO] javax.servlet.jsp:jsp-api ........................... 2.2 -> 2.2.1-b03
[INFO] joda-time:joda-time ....................................... 2.1 -> 2.2
[INFO] mysql:mysql-connector-java .......................... 5.1.21 -> 5.1.24
[INFO] net.sf.ehcache:ehcache ................................ 2.6.5 -> 2.7.0
[INFO] org.apache.tomcat:tomcat-jdbc ....................... 7.0.37 -> 7.0.39
[INFO] org.hibernate:hibernate-c3p0 .............. 4.2.0.Final -> 4.3.0.Beta1
[INFO] org.hibernate:hibernate-core .............. 4.2.0.Final -> 4.3.0.Beta1
[INFO] org.hibernate:hibernate-ehcache ........... 4.2.0.Final -> 4.3.0.Beta1
[INFO] org.hibernate:hibernate-entitymanager ..... 4.2.0.Final -> 4.3.0.Beta1
[INFO] org.hibernate:hibernate-validator ........... 4.3.1.Final -> 5.0.0.CR5
[INFO] org.slf4j:jcl-over-slf4j .............................. 1.7.2 -> 1.7.5
[INFO] org.slf4j:jul-to-slf4j ................................ 1.7.2 -> 1.7.5
[INFO] org.slf4j:slf4j-api ................................... 1.7.2 -> 1.7.5
Из данного вывода можно увидеть какие версии и каких зависимостей поменялись.