Создание Maven-проекта: archetype, структура каталогов и IntelliJ IDEA
Команда из старой инструкции mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 ... отрабатывает без ошибок, но первая же сборка на JDK 21 падает: [ERROR] Source option 7 is no longer supported. Use 8 or later. Шаблон версии 1.4 записал в pom.xml свойства maven.compiler.source и maven.compiler.target со значением 1.7, а современный javac такую версию уже не поддерживает. Сгенерированный проект — это заготовка, которую нужно проверить, и в этом уроке разберём, что именно в ней проверять.
Создать Maven-проект — значит получить каталог с файлом pom.xml (описание проекта и его координат groupId, artifactId, version) и стандартной структурой папок src/main/java, src/test/java и других. Сделать это можно тремя способами: командой mvn archetype:generate по готовому шаблону (archetype), мастером нового проекта в IntelliJ IDEA или вручную — создав pom.xml и каталоги самостоятельно. Результат во всех случаях одинаковый: проект, который собирается командой mvn package.
Способы создать Maven-проект
Maven-проект создают командой mvn archetype:generate (нужен установленный Maven), через мастер New Project в IntelliJ IDEA (Maven встроен в IDE) или вручную: написать pom.xml и создать каталоги. Для учебного консольного приложения все три способа дают почти одинаковый результат; различаются скоростью и тем, сколько лишнего попадает в проект.
| Способ | Что нужно | Плюсы | Нюансы |
|---|---|---|---|
Командная строка: mvn archetype:generate | Установленный Maven и JDK | Работает везде, в том числе без IDE и на сервере; подходит для скриптов | Шаблон может содержать устаревшие настройки — pom.xml нужно проверить |
| IntelliJ IDEA: New Project → Maven | Только IDE (Maven встроен) | Быстрее всего, проект сразу импортирован и готов к запуску | Набор полей мастера немного меняется от версии к версии IDE |
| IntelliJ IDEA: New Project → Maven Archetype | Только IDE | Любой архетип из каталога, в том числе webapp | Те же устаревшие шаблоны, что и в командной строке |
| Вручную | Текстовый редактор | Полный контроль, ничего лишнего; так переводят на Maven уже существующий код | Структуру каталогов нужно знать наизусть (см. таблицу ниже) |
Как установить Maven и проверить установку, описано в уроке Как установить Maven на Windows, Linux и macOS. Для способов через IDE отдельная установка не обязательна.
Что такое Maven archetype
Архетип (archetype) в Maven — это шаблон проекта, опубликованный в репозитории как обычный артефакт: он содержит заготовку pom.xml, каталоги и примеры классов. Команда mvn archetype:generate скачивает архетип и создаёт по нему новый проект, подставляя ваши groupId, artifactId, version и имя пакета.
Архетипы бывают официальные (группа org.apache.maven.archetypes) и сторонние — их публикуют авторы фреймворков. Свой архетип можно создать для типовых проектов компании. Самые известные официальные архетипы:
| artifactId архетипа | Что создаёт | Когда использовать |
|---|---|---|
maven-archetype-quickstart | Проект с packaging = jar, класс App с методом main и тест AppTest | Консольные приложения, библиотеки, учебные проекты — вариант по умолчанию |
maven-archetype-webapp | Проект с packaging = war, каталог src/main/webapp с WEB-INF/web.xml и index.jsp | Веб-приложение на сервлетах/JSP для Tomcat. web.xml из шаблона рассчитан на старые версии спецификации Servlet — проверьте и обновите его |
maven-archetype-simple | Простой проект с минимальной структурой | Когда нужен «чистый» каркас без лишних примеров |
maven-archetype-archetype | Каркас для создания собственного архетипа | Шаблон для однотипных проектов команды |
Spring Boot-проекты обычно создают не архетипом, а генератором start.spring.io (Spring Initializr): он тоже выдаёт обычный Maven-проект с pom.xml и той же структурой каталогов.
Команда mvn archetype:generate
Команда mvn archetype:generate запускает цель generate плагина maven-archetype-plugin и создаёт проект в подкаталоге текущей папки (имя подкаталога = artifactId). Она работает в двух режимах: интерактивном — задаёт вопросы в консоли, и пакетном — все параметры передаются через -D одной командой. Запускать её нужно в папке, где ещё нет pom.xml.
Пакетный режим (рекомендуется)
В пакетном режиме (-DinteractiveMode=false) Maven ничего не спрашивает — команду удобно копировать и повторять. Пример для Linux, macOS и Git Bash:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.5 \
-DgroupId=com.examclouds \
-DartifactId=hello-maven \
-Dversion=1.0-SNAPSHOT \
-DinteractiveMode=false В Windows обратная косая черта как перенос строки не работает (в cmd перенос — ^, в PowerShell — обратная кавычка `), поэтому проще записать команду в одну строку. В PowerShell каждый аргумент с -D заключайте в кавычки:
mvn archetype:generate "-DarchetypeGroupId=org.apache.maven.archetypes" "-DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=1.5" "-DgroupId=com.examclouds" "-DartifactId=hello-maven" "-Dversion=1.0-SNAPSHOT" "-DinteractiveMode=false" Вывод (фрагмент; список параметров зависит от версии архетипа):
[INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.5
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.examclouds
[INFO] Parameter: artifactId, Value: hello-maven
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.examclouds
...
[INFO] Project created from Archetype in dir: /home/user/hello-maven
[INFO] BUILD SUCCESS Параметры команды:
| Параметр | Что задаёт | Если не указать |
|---|---|---|
archetypeGroupId, archetypeArtifactId | Какой архетип использовать | В пакетном режиме используется quickstart; в интерактивном — предлагается список |
archetypeVersion | Версию шаблона — от неё зависит содержимое pom.xml | Версия берётся из каталога архетипов; какая именно — зависит от версии плагина и каталога. Указывайте явно |
groupId, artifactId, version | Координаты нового проекта (см. правила именования) | В пакетном режиме groupId и artifactId обязательны; version по умолчанию — 1.0-SNAPSHOT |
package | Java-пакет для классов-примеров | Равен groupId |
interactiveMode | false — не задавать вопросов | Интерактивный режим |
PowerShell и аргументы с точками
Без кавычек PowerShell разбивает аргумент -DgroupId=com.examclouds на точке и передаёт Maven два слова: -DgroupId=com и .examclouds. Второе Maven принимает за имя фазы и останавливается с ошибкой Unknown lifecycle phase ".examclouds". В cmd и bash этой проблемы нет; в PowerShell пишите "-DgroupId=com.examclouds" или запускайте команду из cmd.
Интерактивный режим
Если запустить mvn archetype:generate без параметров, Maven загрузит каталог архетипов и выведет длинный пронумерованный список с приглашением Choose a number or apply filter. Номер по умолчанию указывает на maven-archetype-quickstart, но сами номера меняются при обновлении каталога, поэтому удобнее ввести фильтр, например quickstart. Затем Maven по очереди спросит версию архетипа, groupId, artifactId, version, package и попросит подтвердить параметры (Y). Интерактивный режим удобен, чтобы посмотреть, какие архетипы существуют; для повторяемого результата используйте пакетный.
Что генерирует quickstart и что поправить в pom.xml
Архетип maven-archetype-quickstart создаёт pom.xml, класс App с методом main, который печатает Hello World!, и тест-заглушку AppTest:
hello-maven/
├── pom.xml
└── src/
├── main/java/com/examclouds/App.java
└── test/java/com/examclouds/AppTest.java Содержимое pom.xml заметно зависит от версии архетипа. Версии до 1.4 включительно используют JUnit 4 (самые старые — даже JUnit 3.8.1) и задают версию Java парой maven.compiler.source/maven.compiler.target со значением 1.7 — с этим JDK 20 и новее уже не компилирует. В версии 1.5 шаблон переведён на JUnit 5 (Jupiter) и свойство maven.compiler.release. После генерации откройте pom.xml и проверьте три вещи:
- Версия Java. Должно быть одно свойство
maven.compiler.releaseс версией вашего JDK или ниже (например,17или21). Паруsource/targetзамените наrelease— почему, объяснено в уроке Что такое Maven. - Версия JUnit. Если в зависимостях
junit:junit3.x или 4.x, а вы пишете тесты на JUnit 5, замените зависимость наorg.junit.jupiter:junit-jupiterсоscope=testи поправьте импорты вAppTest. - Кодировка. Свойство
project.build.sourceEncoding=UTF-8— без него Maven предупреждает о платформенной кодировке, а сборка на разных ОС может по-разному читать строки с кириллицей.
Блок pluginManagement с фиксированными версиями плагинов, который есть в шаблоне, можно оставить: он делает сборку воспроизводимой. Что означает каждый тег, разобрано в уроке Файл pom.xml в Maven.
Как выбрать groupId, artifactId и version
groupId — это «организация или группа проектов» в формате перевёрнутого доменного имени (com.examclouds), artifactId — имя самого проекта строчными буквами через дефис (hello-maven), version — номер версии; на время разработки к нему добавляют суффикс -SNAPSHOT (1.0-SNAPSHOT). Вместе они образуют координаты проекта, по которым его находят в репозитории.
| Координата | Правило | Хорошо | Плохо |
|---|---|---|---|
groupId | Перевёрнутый домен, которым вы владеете (или io.github.ваш-логин); только строчные латинские буквы, цифры и точки | com.examclouds, org.example.shop | MyCompany, com.my-company (дефис недопустим в имени пакета) |
artifactId | Имя проекта строчными буквами, слова через дефис, без пробелов и версии | hello-maven, online-shop | Hello Maven, shop-1.0 |
version | Номер версии; -SNAPSHOT — версия в разработке, без суффикса — выпущенный релиз | 1.0-SNAPSHOT, 1.0.0 | last, v1 final |
Архетип по умолчанию берёт имя Java-пакета из groupId, поэтому классы попадут в com/examclouds/. Если в groupId есть дефис или цифра в начале сегмента, сгенерированный пакет не скомпилируется — задайте корректный -Dpackage явно. Из artifactId и version складывается имя готового файла: hello-maven-1.0-SNAPSHOT.jar. Чем SNAPSHOT-версии отличаются от релизных при работе с репозиторием, описано в уроке Файл pom.xml в Maven.
Структура Maven-проекта
Структура Maven-проекта стандартна (Standard Directory Layout): основной код лежит в src/main/java, ресурсы — в src/main/resources, тесты — в src/test/java и src/test/resources, а результат сборки появляется в target. Maven знает эти пути по умолчанию, поэтому указывать их в pom.xml не нужно — достаточно положить файлы в правильное место.
hello-maven/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/examclouds/App.java
│ │ └── resources/
│ │ └── app.properties
│ └── test/
│ ├── java/
│ │ └── com/examclouds/AppTest.java
│ └── resources/
│ └── test-data.json
└── target/ # created by Maven, do not commit
├── classes/
├── test-classes/
└── hello-maven-1.0-SNAPSHOT.jar | Каталог | Что хранить | Куда попадает при сборке |
|---|---|---|
src/main/java | Исходный код приложения (.java) в папках по пакетам | Компилируется в target/classes → входит в jar/war |
src/main/resources | Конфигурация и данные: .properties, .xml, .yml, шаблоны, SQL-скрипты | Копируется в target/classes → в корень classpath и в jar |
src/test/java | Тесты (JUnit) в тех же пакетах, что и проверяемый код | Компилируется в target/test-classes, в jar не попадает |
src/test/resources | Файлы, нужные только тестам: тестовые данные, конфигурация для тестов | Копируется в target/test-classes, в jar не попадает |
src/main/webapp | Только для packaging = war: WEB-INF/web.xml, JSP, статические файлы | В корень war-архива |
target | Ничего не хранить вручную — это результат сборки | Удаляется командой mvn clean; добавьте в .gitignore |
Папки внутри src/main/java повторяют пакеты: класс com.examclouds.App лежит в src/main/java/com/examclouds/App.java. Тест для него принято класть в тот же пакет в src/test/java — тогда тесту доступны и package-private члены класса.
Что будет, если положить файл не туда
Maven не ищет файлы по всему проекту: компилятор берёт только .java из каталогов java, а копирование ресурсов — только из resources. Ошибка размещения часто не ломает сборку, а проявляется позже — при запуске или в тестах.
| Что сделали | Что произойдёт |
|---|---|
Класс с JUnit-тестом положили в src/main/java | Сборка падает на компиляции: package org.junit.jupiter.api does not exist — у зависимости JUnit scope = test, и основной код её не видит |
config.properties положили рядом с классами в src/main/java | Сборка успешна, но файла нет в target/classes и в jar: getClass().getResourceAsStream("/config.properties") вернёт null |
.java-файл положили в src/main/resources | Файл копируется как текст и не компилируется; при запуске — ClassNotFoundException или Could not find or load main class |
Тест назвали CheckCalculator.java | Компилируется, но не запускается: плагин Surefire по умолчанию выполняет классы с именами Test*, *Test, *Tests, *TestCase. В выводе mvn test — Tests run: 0 или нет блока с тестами вовсе |
Создали папку src/java или source/main/java | Maven её не видит: No sources to compile, jar пустой (только манифест) |
Стандартные пути можно переопределить в pom.xml, но делать это стоит только при переводе на Maven старого проекта, который нельзя реорганизовать. Как это настраивается, показано в уроке Файл pom.xml в Maven.
Maven-проект в IntelliJ IDEA
Чтобы создать Maven-проект в IntelliJ IDEA, откройте мастер нового проекта (File → New → Project), выберите генератор Java с системой сборки Maven или генератор Maven Archetype, укажите имя, расположение, JDK и координаты GroupId/ArtifactId. IDE создаст pom.xml и стандартные каталоги и сразу импортирует проект. Отдельно устанавливать Maven не нужно — он встроен в IDE.
Названия пунктов ниже соответствуют актуальным версиям IntelliJ IDEA (Community и Ultimate); в старых версиях мастер выглядит иначе, но поля те же.
Новый проект: поля мастера
| Поле | Что указать |
|---|---|
| Name | Имя проекта и папки; IDE подставит его и в ArtifactId |
| Location | Родительский каталог; лучше без пробелов и кириллицы в пути |
| Build system | Maven (в генераторе Java); по умолчанию может стоять IntelliJ — тогда проект будет без pom.xml |
| JDK | Установленный JDK 17 или 21; при его отсутствии IDE предложит скачать |
| Add sample code | Создать класс Main с методом main |
| GroupId, ArtifactId (Advanced Settings) | Координаты проекта по правилам выше |
| Catalog, Archetype, Version (только в генераторе Maven Archetype) | Каталог архетипов, сам архетип (например, org.apache.maven.archetypes:maven-archetype-quickstart) и его версия — то же, что параметры archetypeArtifactId и archetypeVersion в командной строке |
Генератор Java с Build system = Maven обычно создаёт более аккуратный pom.xml, чем старые архетипы: версия Java в нём берётся из выбранного JDK. Сгенерированный файл всё равно стоит просмотреть по списку из раздела про quickstart.
Окно Maven и синхронизация после правки pom.xml
Окно инструментов Maven (обычно на правой боковой панели) показывает проект в виде дерева: Lifecycle — фазы сборки, которые запускаются двойным щелчком (clean, compile, test, package…), Plugins — подключённые плагины и их цели, Dependencies — дерево зависимостей.
IntelliJ IDEA не перечитывает pom.xml на каждое нажатие клавиши. После правки файла в редакторе появляется плавающая кнопка Load Maven Changes (сочетание по умолчанию — Ctrl+Shift+O в Windows и Linux, Cmd+Shift+I в macOS). В окне Maven есть кнопка Reload All Maven Projects с тем же действием. Пока изменения не загружены, новая зависимость подсвечивается красным в коде, хотя в pom.xml она уже есть.
Импорт существующего проекта
Готовый Maven-проект (например, клонированный из Git) открывают через File → Open: выберите файл pom.xml и в диалоге нажмите Open as Project (можно выбрать и папку, в которой лежит pom.xml). IDE сама настроит каталоги исходников, JDK и зависимости. Если pom.xml лежит в подпапке и IDE его не распознала, щёлкните по файлу правой кнопкой и выберите Add as Maven Project.
Встроенный Maven или свой: настройки
Настройки Maven находятся в Settings (в macOS — Preferences) → Build, Execution, Deployment → Build Tools → Maven:
- Maven home path — Bundled (встроенный в IDE) или путь к вашей установке. Укажите свою установку, если нужна та же версия Maven, что в терминале и на CI.
- User settings file и Local repository — путь к
settings.xmlи к локальному репозиторию (по умолчанию~/.m2), подробнее — в уроке Виды репозиториев в Maven. - Подраздел Runner — JDK, на котором запускается Maven, и опция Delegate IDE build/run actions to Maven: при ней кнопки Build и Run выполняются через Maven, а не через собственный сборщик IDE.
Если в проекте есть Maven Wrapper, IDE может использовать его версию Maven — что такое mvnw, описано в уроке Что такое Maven.
Неочевидный момент: в IDE собирается, в терминале — нет
Встроенный Maven доступен только внутри IDE: во вкладке Terminal команда mvn не найдётся, если Maven не установлен в системе. Кроме того, IDE и терминал могут запускать Maven на разных JDK (Runner в настройках IDE против JAVA_HOME). Если проект собирается кнопкой в IDE, но падает в терминале с ошибкой версии Java, сравните строку Java version в выводе mvn -version с JDK в настройках Runner.
Создание Maven-проекта вручную
Вручную Maven-проект создаётся за две минуты: каталог проекта, внутри — pom.xml с координатами и версией Java, и папки src/main/java и src/test/java с подкаталогами пакета. Этим же способом переводят на Maven уже существующий код: исходники переносят в src/main/java, а библиотеки из папки lib заменяют зависимостями в pom.xml.
# Linux, macOS, Git Bash
mkdir -p hello-maven/src/main/java/com/examclouds hello-maven/src/main/resources hello-maven/src/test/java/com/examclouds
# Windows (PowerShell)
New-Item -ItemType Directory -Force hello-maven/src/main/java/com/examclouds, hello-maven/src/main/resources, hello-maven/src/test/java/com/examclouds В корень hello-maven положите pom.xml — минимальный рабочий вариант из 12 строк приведён в уроке Что такое Maven, а класс с методом main — в src/main/java/com/examclouds:
package com.examclouds;
public class App {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} Первая сборка и запуск
Первую сборку проверяют тремя командами в корне проекта (там, где pom.xml): mvn compile компилирует код в target/classes, mvn test дополнительно запускает тесты, mvn package собирает jar в target. Каждая следующая команда выполняет и предыдущие шаги. Первый запуск дольше обычного: Maven скачивает плагины в локальный репозиторий.
cd hello-maven
mvn test Вывод (фрагмент для проекта из quickstart):
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.examclouds.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...
[INFO] BUILD SUCCESS mvn package
java -cp target/hello-maven-1.0-SNAPSHOT.jar com.examclouds.App Вывод:
[INFO] Building jar: /home/user/hello-maven/target/hello-maven-1.0-SNAPSHOT.jar
[INFO] BUILD SUCCESS
Hello World! Обратите внимание: запуск через java -jar target/hello-maven-1.0-SNAPSHOT.jar завершится ошибкой no main manifest attribute, in target/hello-maven-1.0-SNAPSHOT.jar — архетип не прописывает главный класс в манифест jar. Поэтому класс указывают явно через -cp; как добавить Main-Class в манифест, показано в уроке Использование плагинов в Maven. Если проект использует сторонние библиотеки, их тоже нужно добавить в -cp — обычный jar их не содержит.
Почему mvn package сам выполняет компиляцию и тесты и чем фазы отличаются друг от друга, разобрано в уроке Maven — жизненный цикл сборки. Как запускать Java-программы без Maven, через javac и java, — в уроке Создание и запуск Java-приложения.
На чём чаще всего ошибаются
Большинство проблем при создании первого Maven-проекта связано с тем, где запускается команда, какой JDK использует Maven и в какой каталог положен файл. Ниже — сообщения об ошибках и их исправление.
| Симптом | Причина | Как исправить |
|---|---|---|
The goal you specified requires a project to execute but there is no POM in this directory | Команда запущена не в корне проекта — например, сразу после archetype:generate, не перейдя в созданную папку | cd hello-maven и повторить команду |
Source option 7 is no longer supported. Use 8 or later. | Старый архетип задал source/target 1.7 | Заменить на maven.compiler.release = 17 или 21 |
release version 21 not supported | Maven запущен на JDK старше версии в release | Проверить JDK в mvn -version и JAVA_HOME или уменьшить release |
Unknown lifecycle phase ".examclouds" | PowerShell разбил аргумент -DgroupId=com.examclouds | Взять каждый аргумент -D... в кавычки |
| IDE не подсвечивает код, нет окна Maven, импорты красные | Проект открыт как обычная папка, pom.xml не импортирован | Правый щелчок по pom.xml → Add as Maven Project, или File → Open → pom.xml → Open as Project |
Новая зависимость в pom.xml, но класс не находится в IDE | Изменения pom.xml не загружены | Load Maven Changes или Reload All Maven Projects |
package org.junit.jupiter.api does not exist при mvn compile | Тест лежит в src/main/java или у JUnit неверная версия/артефакт | Перенести тест в src/test/java; проверить зависимость JUnit |
Типичный промах: тест, который молча не запускается
Тест-класс в правильном каталоге src/test/java, но с именем вроде CalculatorCheck, компилируется без ошибок, а mvn test завершается BUILD SUCCESS — потому что ни одного теста не выполнилось. В IDE тот же класс запускается кнопкой Run, и это усиливает путаницу. Называйте тестовые классы по шаблону *Test — тогда их найдёт и плагин Surefire, и CI-сервер.
Часто задаваемые вопросы
Обязательно ли использовать archetype, чтобы создать Maven-проект?
Нет. Архетип — лишь способ быстро получить заготовку. Maven-проектом каталог делает файл pom.xml и стандартная структура папок, и их можно создать вручную или мастером IntelliJ IDEA без архетипа. Пошагово — в разделе Создание Maven-проекта вручную.
Как превратить обычный Java-проект в Maven-проект?
Создайте в корне pom.xml с координатами и версией Java, перенесите исходники в src/main/java с сохранением папок пакетов, файлы настроек — в src/main/resources, тесты — в src/test/java. Jar-файлы из папки lib замените зависимостями в pom.xml. В IntelliJ IDEA после этого выберите на pom.xml пункт Add as Maven Project.
Нужно ли хранить в Git каталог target и файлы .idea?
Каталог target — нет: это результат сборки, он пересоздаётся командой mvn package. Файлы IDE (.idea, *.iml) для Maven-проекта тоже не обязательны — IntelliJ IDEA восстанавливает настройки из pom.xml. В репозиторий кладут pom.xml, src и, если используется, Maven Wrapper.
Где лучше хранить тестовые данные: в src/test/resources или в src/main/resources?
В src/test/resources. Эти файлы видны тестам через classpath, но не попадают в итоговый jar. Если положить тестовые данные в src/main/resources, они уйдут в рабочую сборку и могут подменить настоящую конфигурацию, если имена файлов совпадут.
Как создать Maven-проект на Spring Boot?
Через генератор Spring Initializr: на сайте start.spring.io выберите Project = Maven, версию Java и нужные модули, скачайте архив и откройте pom.xml в IDE как проект. В IntelliJ IDEA Ultimate тот же генератор встроен в мастер нового проекта. Структура каталогов будет стандартной Maven-структурой.
Комментарии