JavaRush/Java блог/Java-проекты/Все, что вы хотели знать о Maven - "Java-проект от А до Я...
Roman Beekeeper
35 уровень

Все, что вы хотели знать о Maven - "Java-проект от А до Я"

Статья из группы Java-проекты
участников
Всем привет, дорогие друзья. Хочу сразу извиниться: помнится, я обещал, что буду писать по статье раз в неделю. Не получилось. Просто руки не дошли до того, чтобы сесть и нормально написать, а делать так-сяк не хочу. Ныть о причинах не буду, так как мне оно не нужно, и вам уж точно не интересно. Проект не мертв, он был в стазисе :) Мы продолжаем! И сегодняшний материал посвящен Мавену. "Java-проект от А до Я": Все, что вы хотели знать о Maven - 1

Поговорим о Мавене

Сперва его нужно установить. Разумеется так как у меня мак, показать установку я смогу только для мака. Только вот незадача. Я его давно уже установил, поэтому вам придется сделать это самостоятельно :)
Инструкция по установке Maven есть в этом материале.

Зачем нам Мавен

Мавен — это инструмент для сборки проекта, наряду с 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 на практике.

Список всех материалов серии в начале этой статьи.

Комментарии (17)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Anonymous #2856674 Software Developer
24 февраля, 08:17
По поводу отсутствующего pom.xml Надо добавить Maven в ваш проект в Intelej IDEA Сделать это можно щелкнув прав. кнопкой мыши на корне проекта - add framework support и выбрать maven Если вдруг у вас нет Maven, то скорее всего его следует установить - загуглите как. Этот момент я на самом деле не помню точно - всегда ли есть флаг Maven или нет
Freeflyfish
Уровень 22
23 ноября 2023, 08:15
Да, первые статьи так хорошо зашли, но дальше видимо не было времени, так как непонятно для кого написано про Мавен, ничего не соответствует действиям и картинкам, более того написано делайте свое так будет лучше, но как , для этого же надо как-то показать, и тут бах помник который есть только в проекте romankh3, и никаких пояснений как создать свой, такой же он будет или нет, от чего завист его наполнение, можно ли просто скопипастить, ниже пишут, что в следующей статье все будет, а там еще хуже, пишут создать папки в проекте с main и test и подключить Maven, а на скрине папок нет, тесты тоже уже готовы, В общем жаль, когда столько времени теряешь на то, чтобы разобраться в чужой статье и что же на самом деле должно быть у тебя, то в голове не откладывается четкого понятия что да как, хотя по сути в названии от А до Я, не для новичков совсем, для тех кто уже имел дело и не раз. Если разберусь, то боюсь представить что дальше, ведь это только начало... Автор конечно молодец, для себя памятка хорошая, наверное, но для учащегося только пугает, что опять ничего не понятно и напрасно тратишь время, так как все больше и больше закапываешься в неясностях. Это не хэйт если что, может автор подправит свои статьи позднее или будет писать подробнее с пояснениями, лучше больше - зато понятнее... В любом случае Спасибо за труды!
Кирилл
Уровень 35
21 марта 2023, 17:41
Не совсем пойму, ссылка, с которой копируется, больше не действует?
Кирилл
Уровень 35
17 марта 2023, 19:26
Это жесть жестющая)))
Denis
Уровень 33
3 ноября 2022, 09:25
Я клонировал проект по указанной ссылке. Там не было файла pom.xml. Далее в статье идет описание структуры блоков xml-фала и тут было бы удобно читать статью и паралельно изучать структуру файла "pom.xml", но где взять файл "pom.xml"? Создать блокнотом?
Alex T
Уровень 35
5 мая 2021, 12:19
в той части, где объясняется про плагины - первый скриншот с одним плагином, но текст под ним уверяет, что на нем 2 плагина. в следующем скриншоте плагинов уже действительно 2.
Павел
Уровень 35
13 апреля 2021, 07:38
Чел выложил свой перевод книги Введение в Maven там же есть ссылка на оригинал. А вот цикл старых статей, которые принесут очень большую пользу, если читать внимательно и задаваться вопросом о схемах .xml файлов и основных парадигмах программирования, как императивная (процедурное, ооп) и декларативная (SQL, maven). Читая статью о парадигмах (что по ссылке) явно видишь, что JR делали не профессионалы в обучении((.
Wally Dator
Уровень 26
17 марта 2021, 19:37
я вернулся!
Leftover
Уровень 39
16 марта 2021, 07:43
Непонятно в какой момент и откуда появляется pom.xml :) Например можно сделать правый клик на корне проекта, выбрать Add Framework Support. Выбрать Maven, в появивщемся pom.xml заполнить groupId.
Roman Beekeeper тг-канал по java разработ в t.me/romankh3
16 марта 2021, 08:02
Я перечитаю ещё раз статью и проверю, спасибо.
Leftover
Уровень 39
16 марта 2021, 08:32
Оказалось, что все это есть в следующей статье.
Roman Beekeeper тг-канал по java разработ в t.me/romankh3
16 марта 2021, 08:53
Да, статья разделена на две части)
Roman Beekeeper тг-канал по java разработ в t.me/romankh3
11 марта 2021, 20:38
⚡️UPDATE⚡️ Друзья, создал телеграм-канал 🤓, в котором освещаю свою писательскую деятельность и свою open-source разработку в целом. Присоединяйтесь ✌️