Всем привет, дорогие друзья.
Хочу сразу извиниться: помнится, я обещал, что буду писать по статье раз в неделю. Не получилось. Просто руки не дошли до того, чтобы сесть и нормально написать, а делать так-сяк не хочу. Ныть о причинах не буду, так как мне оно не нужно, и вам уж точно не интересно.
Проект не мертв, он был в стазисе :) Мы продолжаем! И сегодняшний материал посвящен Мавену.
!["Java-проект от А до Я": Все, что вы хотели знать о Maven - 1]()
Поговорим о Мавене
Сперва его нужно установить. Разумеется так как у меня мак, показать установку я смогу только для мака. Только вот незадача. Я его давно уже установил, поэтому вам придется сделать это самостоятельно :)
Зачем нам Мавен
Мавен — это инструмент для сборки проекта, наряду с Gradle и Ant. Просто в силу того, что я буду использовать его в JRTB (JavaRush Telegram Bot), хочу ввести вас в курс дела.
Без системы сборки сейчас не создают ни одного проекта, потому что это упрощает нашу жизнь многократно. Это позволяет:
- • подтянуть все необходимые библиотеки (в терминах инструментов для сборки — зависимостей (то есть dependency));
- • определить то, как именно нужно собирать проект и во что (например, хотим мы собирать в WAR или JAR или executable JAR);
- • задать версию проекта в одном месте так, чтобы при сборке была указана она;
- • описать проект и его жизненный цикл;
- • добавлять так называется плагины (калька с английского слова Plugin);
- • публиковать библиотеки в общем хранилище, чтобы другие проекты смогли подтянуть их как зависимости.
В общем, дел делает много, и все они полезные.
Скажу так: для начинающих инженеров не обязательно знать весь функционал от корочки до корочки. Здесь, как и с гитом, важно понимать основу и общие понятия.
Этим мы и займемся.
Для нас Мавен начинается с XML файла в корне нашего проекта с именем
pom.xml. Будем делать все на практике, поэтому для начала создадим наш первый проект в сообществе JavaRush Community.
Чтобы сделать все по уму, я воспользуюсь
шаблоном для репозитория, где уже настроены базовые вещи,
которые я описывал как-то на JR.
Чтобы создать, заходим в репозиторий с шаблоном и нажимаем кнопку
Use this template:
!["Java-проект от А до Я": Все, что вы хотели знать о Maven - 2]()
В результате у нас есть первый репозиторий в нашем сообществе :)
Стягиваем проект себе локально. Для этого через идею заходим в
File -> New -> Project from Version Control.
В появившемся окне вводим ссылку на проект на гитхабе (результат будет лучше, если каждый создаст отдельно у себя такой же проект и пройдет все шаги со мной):
!["Java-проект от А до Я": Все, что вы хотели знать о Maven - 3]()
Нажимаем
Clone, и
дело в шляпе проект клонирован.
pom.xml всему голова
Все, что нужно, находится в pom.xml. Вся информация о проекте, ее разработчике и том, на каком удаленном репозитории хранится проект.
Нас на старте интересуют следующие блоки:
<project/> — это главный блок, в котором содержится вся информация о проекте. Все остальные будут явно или транзитивно находиться в нём. Внутри открывающегося тега написано что-то такое:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
И ко всему прочему следующая строка тоже пишется во всех помниках (сленг такой, мол, от pom.xml :)).
<modelVersion>4.0.0</modelVersion>
А вот дальше уже интереснее: будем описывать, как мы идентифицируем проект, который описывает наш помник. На примере моей библиотеки я опишу, а потом будем добавлять это в наш помник, в новосозданный проект:
<groupId>com.github.romankh3</groupId>
<artifactId>image-comparison</artifactId>
<version>4.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Image Comparison</name>
Главное здесь:
- • groupId — это идентификатор девелоперской организации или отдельного инженера. Обычно это домен в обратном порядке. Для примера здесь описан аккаунт romankh3 на гитхабе. Это очень важно. Скажем, у Spring экосистемы это com.springframework. Так можно отличить оригинальный проект от чьего-то ответвления или просто по совпадению имени проекта.
- • artifaceId — это уже имя конкретного проекта, который описывается в этом помнике.
- • version — версия этого проекта. Здесь все ясно, как божий день: добавил новый функционал, починил старый, отрефакторил или сделал какие-то еще изменения — версию увеличил.
- • packaging — здесь мы описываем, как Мавен должен собирать наш проект. То ли в Jar, то ли в War, то ли еще какие-то другие.
- • name — здесь уже более приятное для глаз название проекта.
Есть еще некоторые вещи, которые вовсе не обязательны к заполнению — Мавен заработает и без них, — но если нужно опубликовать библиотеку для общего пользования, добавить их точно стоит.
Какие это вещи?
- • путь к репозиторию проекта, откуда его можно скачать
<url>https://romankh3.github.io/image-comparison/</url>
- • лицензия, под которой этот проект распространяется. Причем она может быть не одна, и поэтому задать нужно таким образом:
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
- • информация о разработчиках, которые проект создавали/создают:
<developers>
<developer>
<id>romankh3</id>
<name>Roman Beskrovnyi</name>
<email>roman.beskrovnyy@gmail.com</email>
</developer>
</developers>
- • блок scm, который описывает, как можно получить доступ к проекту:
<scm>
<connection>git@github.com:romankh3/image-comparison.git</connection>
<developerConnection>git@github.com:romankh3/image-comparison.git</developerConnection>
<url>https://github.com/romankh3/image-comparison</url>
</scm>
После того, как мы описали общую информацию, можно добавлять блок с зависимостями (dependencies):
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.26.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.romankh3</groupId>
<artifactId>image-comparison</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Здесь я добавил две библиотеки для тестирования: они всегда нужны. Как вы могли уже заметить, у зависимостей есть Scope — область применения. В нашем случае указан
test, что значит, что в главном коде мы просто не увидим эту зависимость.
Далее, чтобы все было по красоте, можно воспользоваться отдельным тегом для выведения версий
<properties/>:
<properties>
<mockito.version>2.26.0</mockito.version>
<junit.version>5.5.2</junit.version>
<image.comparison.version>4.3.0</image.comparison.version>
</properties>
Так что блок депенденси можно обновить, используя конструкцию
${PROPERTY_NAME}:
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.romankh3</groupId>
<artifactId>image-comparison</artifactId>
<version>${image.comparison.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Далее идет большой блок
<build/>, в котором находится важный блок
<plugins/>, при помощи которого можно настраивать процесс сборки. Внутри блока
<plugins/> можно добавить один и больше плагинов, как например здесь:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Здесь видно, что я добавил два плагина —
maven-source-plugin и
maven-javadoc-plugin. В каждом из плагинов есть настройки, атрибуты (параметры), которые можно задавать, тем самым настраивая плагины. Для нас в будущем это будет интересно. Пока что запомним и пойдем дальше.
Таким же образом, как и для зависимостей вынесем версии плагинов в
<properties/>.
Исходя из этого, можно создать следующий помник:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.javarushcommunity</groupId>
<artifactId>maven-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Demo Project</name>
<url>https://github.com/javarushcommunity/maven-demo/</url>
<properties>
<mockito.version>2.26.0</mockito.version>
<junit.version>5.5.2</junit.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<source.plugin.version>3.2.0</source.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${source.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${javadoc.plugin.version}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Maven lifecycle
У Мавена есть такая вещь, как maven lifecycle. Стоит сказать, что это набор задач (task), которые может выполнить мавен. Задачи могут быть и другие, помимо maven lifecycle.
О чем идет речь?
Есть набор команд, при помощи которых можно собирать проект (
билдить… опять, конечно, калька с английского, но без этого никуда), удалять билды, которые собрал Мавен, устанавливать в Maven local так, чтобы можно было локально подтягивать себе проект как зависимость, и так далее. Сейчас поговорим обо всем подробнее.
Перед тем, как написать свое мнение по поводу этих команд, решил почитать, что пишут в интернетах об этом деле… и понял, что описано очень сложно. Нам для работы, для начальной работы, нужно
несколько команд.
Опишем их:
- • compile — компилировать проект. Это первый этап: в ходе него можно посмотреть, нет ли ошибок компиляции в проекте. Иногда бывает разная чехарда с работой в IDEA, из-за чего появляются проблемы с компиляцией там, где их не должно быть. Так что эта команда расставит все точки над i.
- • test — запускает все тесты, которые работают над JUnit и находятся там, где их ожидает Мавен (src/test/java ваш капитан).
- • package — это следующая команда, которая включает две предыдущие: то есть, внутри нее вначале запускается команда compile, потом на скомпилированный проект натравливается команда test, ну и если все ок и здесь, запускается создание архива (того архива, который мы выбираем в <packaging/>))
- • install — когда мы устанавливаем Мавен на машину, у нас появляется локальный гит-репозиторий, в котором хранятся библиотеки, которые мы скачиваем для проектов. Но прелесть Мавена заключается еще и в том, что мы при помощи команды install можем добавить наш проект в локальный гит-репозиторий и локально использовать наш проект как зависимость. Не верите? Попробуйте :) Таким образом можно достаточно быстро посмотреть, как будет выглядеть ваш проект как зависимость у другого.
- • deploy — это венец всего, что было до этого. Команда, которая дарит возможность добавлять проект не только в локальный репозиторий как install, но и на удаленный, откуда каждый человек с доступом сможет использовать его как зависимость.
- • verify — команда, которая все проверит и скажет, готов ли проект к деплою.
- • clean — разумеется, скомпилированные файлы и архив где-то должны храниться. Для этого у Мавена есть папка target. Это данные, которые проекту не нужны. И перед тем, как собирать проект заново, хорошо бы удалить все, что было до этого. Вот для этого и служит команда clean.
Maven Plugins
Хотел еще поговорить о плагинах, но статья и так уже вышла большая. Будет вам домашним заданием. Разберитесь, что это такое и как этим пользоваться.
В продолжении статьи разберемся с Maven на практике.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ