JavaRush /Курсы /Java Server /Gradle Wrapper: способ сборки

Gradle Wrapper: способ сборки

Java Server
2 уровень , 1 лекция
Открыта

1. Gradle и Wrapper: gradle vs gradlew

В начале очень легко перепутать две похожие вещи: gradle как программу и gradle Wrapper как способ её запускать. Звучат они почти одинаково — как «кофе» и «кофеварка», только последствия путаницы обычно бодрят сильнее утреннего эспрессо. Давайте спокойно разберём, что именно вы запускаете и почему в учебном проекте мы выбираем только один путь.

Представьте, что вы пишете в терминале:

# Запуск Gradle, который установлен в системе (локально на вашей машине)
gradle build

Это означает: «возьми Gradle, который установлен на моём компьютере, и попробуй собрать проект». А теперь сравните с:

# Запуск Gradle через Wrapper (версия Gradle берётся из настроек проекта)
./gradlew build

Это уже означает: «возьми Gradle, который прописан в проекте, и собери проект». Разница кажется косметической — всего‑то две точки и слэш, — но инженерно это два разных мира.

Системный gradle живёт по правилам вашей машины. У вас может быть Gradle 8.x, у вашего друга — 9.x, а у преподавателя — вообще ничего (и он не обязан угадывать, что вы там поставили). В итоге получается классическая ситуация: «у меня собирается», «у тебя не собирается», «а давай ты просто переустановишь всё на всякий случай». Это выглядит как план, но это плохой план.

Wrapper делает наоборот: кладёт в репозиторий «точку входа», которая гарантирует, что проект запускается одним и тем же Gradle независимо от того, кто его запускает. В нашем курсе это особенно важно, потому что baseline зафиксирован: Gradle Wrapper 9.4.0, Kotlin DSL, Java 25. Нам нужно, чтобы вы могли открывать любой пример из лекции и получать тот же результат, а не проходить квест «угадай версию».

Для наглядности можно запомнить короткую формулу:

Команда Кто выбирает версию Gradle Почему это важно
gradle build
ваша ОС / ваша локальная установка проект становится «привязанным к машине»
./gradlew build
сам проект (через Wrapper) проект становится воспроизводимым

И да, иногда системного gradle у вас вообще не будет — и это нормально. В нашем курсе не нужно отдельно ставить Gradle в систему. Если вам очень хочется что‑то поставить руками — лучше поставьте себе напоминание всегда собирать проект через Wrapper. Оно полезнее.

2. Wrapper: файлы и роли

Когда вы впервые видите Wrapper‑файлы в проекте, рука так и тянется подумать: «О, мусор! Это же не Java‑код». Реакция почти естественная, особенно если до этого вы писали маленькие программы, которые живут в одном файле. Но для backend‑проекта, даже учебного, эти файлы — как ключи от квартиры: вы можете быть прекрасным разработчиком, но без ключей внутрь не попадёте.

Минимальный Wrapper‑набор выглядит так:

# Структура файлов, которые обеспечивают запуск Gradle через Wrapper
readlater-starter/
├── gradlew
├── gradlew.bat
└── gradle/
    └── wrapper/
        ├── gradle-wrapper.jar
        └── gradle-wrapper.properties

Давайте переведём это с формата «увидел в дереве проекта» на человеческий смысл.

gradlew — это скрипт для macOS/Linux. Он запускается как исполняемый файл из корня проекта и является вашим главным входом. gradlew.bat — то же самое, но для Windows (batch‑скрипт). Это не «два разных варианта на выбор», а два варианта для разных ОС.

В папке gradle/wrapper/ лежат два критически важных файла. gradle-wrapper.properties — конфигурация Wrapper, в ней как раз фиксируется, какую версию Gradle использовать. gradle-wrapper.jar — маленькая Java‑программа (да, jar), которая умеет скачать нужный Gradle и потом запустить его так, как надо проекту.

Чтобы было проще, вот небольшая «шпаргалка» в виде таблицы:

Файл Зачем нужен Можно ли удалять
gradlew
запуск Gradle через Wrapper на macOS/Linux нет
gradlew.bat
запуск Gradle через Wrapper на Windows нет
gradle/wrapper/gradle-wrapper.properties
фиксирует версию Gradle и настройки дистрибутива нет
gradle/wrapper/gradle-wrapper.jar
реализация Wrapper, которая скачивает и запускает Gradle нет

Здесь легко зависнуть на вопросе: а откуда эти файлы вообще берутся в самом первом состоянии проекта? Их не пишут руками. Обычно они уже приходят вместе со стартовым каркасом проекта — например, если вы создаёте Gradle‑проект из шаблона или берёте готовый учебный репозиторий. Дальше Wrapper живёт в репозитории как часть проекта, и все команды идут только через него.

Слово «нет» в колонке «можно ли удалять» — не потому, что мы вредные. А потому, что если вы удалите Wrapper‑файлы, проект перестанет иметь универсальную точку входа, и мы откатимся в эпоху «поставь Gradle сам как‑нибудь».

3. Версия Gradle в gradle-wrapper.properties

Если вы ищете в проекте место, где «на самом деле» зафиксирована версия Gradle, это не build.gradle.kts и не IDE‑настройка. Это файл gradle/wrapper/gradle-wrapper.properties. Он маленький, скучный и именно поэтому надёжный: никакой магии, только текст, который читает Wrapper.

Самая важная строка там обычно выглядит так:

# Откуда Wrapper скачивает Gradle (и по этой строке фиксируется версия)
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip

Эта запись буквально означает: «если нужно запустить Gradle, возьми дистрибутив gradle-9.4.0-bin.zip с официального сайта Gradle». То есть версия 9.4.0 зафиксирована в проекте. Не «последняя на сегодня», не «какая установлена» и не «та, что у меня в IDE». А та, с которой этот репозиторий должен жить.

Почему это важно даже для новичка, который пока не собирает многомодульных монстров? Потому что Gradle — живой инструмент. В разных версиях отличаются детали Kotlin DSL, доступные возможности, поведение некоторых задач и даже сообщения об ошибках. А вы сейчас учитесь, и вам нужно, чтобы пример из лекции совпадал с тем, что происходит на вашем компьютере.

У Wrapper есть и другие свойства: где хранить скачанный дистрибутив, как раскладывать файлы и так далее. Но в рамках нашего курса достаточно держать в голове один якорь: distributionUrl фиксирует версию Gradle и делает запуск воспроизводимым.

Ещё одна деталь: bin в имени архива означает «binary distribution», то есть обычный рабочий вариант. Существуют и другие варианты дистрибутива, но мы не превращаем этот курс в курс по build‑инженерии. Наша цель проще: одинаковый запуск у всех.

4. Первый запуск: скачивание Gradle

Первый запуск Wrapper часто пугает новичков: вы вводите команду, и вместо мгновенного «успех!» видите, как что‑то скачивается, шуршит, распаковывается. Тут важно не сделать вывод «у меня всё сломалось» и не побежать переустанавливать Java, IDE и, на всякий случай, клавиатуру.

Механика примерно такая: когда вы запускаете ./gradlew ..., Wrapper проверяет, есть ли нужная версия Gradle в локальном кэше. Если нет — скачивает по distributionUrl, распаковывает и только потом запускает нужную задачу (build, run и т.д.).

В упрощённом виде это выглядит так:

# Вся логика ниже — про то, что делает Wrapper перед тем, как запустить сборку
Вы запускаете ./gradlew build
→ Wrapper читает gradle-wrapper.properties
→ Видит gradle-9.4.0-bin.zip
→ Если Gradle 9.4.0 ещё нет локально — скачивает
→ Запускает Gradle 9.4.0 и выполняет build

Где это хранится? Обычно в домашней директории пользователя, в папке .gradle. То есть скачанный Gradle — это не часть репозитория, а локальный кэш на вашей машине. Поэтому первый запуск может быть заметно медленнее, а второй и третий — уже значительно быстрее.

Если хочется увидеть, что Wrapper действительно живой и работает, можно безопасно выполнить команду, которая ничего не компилирует, а просто показывает информацию о Gradle:

# Проверяем, какую версию Gradle реально запускает Wrapper
./gradlew --version
# Gradle 9.4.0
# Kotlin: ...
# JVM: ...

Комментарий под командой — это не точный «байт в байт» вывод, он может отличаться деталями. Но смысл вы ловите: вы увидите версию Gradle, и это будет именно та версия, что зафиксирована в Wrapper.

Если первая загрузка идёт долго, чаще всего причина прозаична: медленный интернет, первый запуск, иногда корпоративный прокси. Но на уровне курса мы воспринимаем «первый запуск качает Gradle» как нормальную часть жизни проекта. Важно только помнить: это происходит один раз на версию Gradle и потом кэшируется.

5. Задачи через Wrapper

Когда говорят «запускать через Wrapper», это не философия, а вполне конкретный формат команд. Вы запускаете скрипт из корня проекта и передаёте ему имя задачи. Если бы Gradle был кофемашиной, то Wrapper был бы кнопкой «включить», а задача — командой «сделай латте». Да, сравнение странное, но оно внезапно помогает запомнить структуру.

Общий шаблон команды такой:

# <taskName> — это имя задачи Gradle, например build/run/test и т.д.
./gradlew <taskName>

Например, самые базовые задачи, которые уже скоро будут у нас активно использоваться, выглядят так:

# Собрать проект (компиляция, тесты, упаковка — зависит от настроек проекта)
./gradlew build
# Запустить приложение (если в проекте настроена задача run)
./gradlew run

На Windows вместо ./gradlew обычно используется gradlew.bat (и это именно имя файла, а не «что‑то из IDE»):

REM На Windows используем batch-скрипт Wrapper из корня проекта
gradlew.bat build
gradlew.bat run

Поскольку даже здесь легко запутаться, вот маленькая таблица‑напоминалка:

ОС Команда
macOS / Linux
./gradlew build
Windows
gradlew.bat build

Теперь про странный префикс ./. Он означает «запусти файл из текущей директории». На Unix‑подобных системах (Linux/macOS) текущая папка не входит в PATH по умолчанию, и это сделано специально из соображений безопасности. Поэтому gradlew без ./ часто не запускается. Не потому, что «у вас не тот терминал», а потому, что так устроена система.

Ещё одна полезная привычка: всегда запускать команды из корня проекта — из той папки, где лежат gradlew, build.gradle.kts и settings.gradle.kts. Если вы стоите где‑нибудь в глубине src/main/java, Wrapper физически может не находиться по пути, и команда не сработает. Это не «Gradle странный», это вы просто стоите не там.

6. Wrapper в репозитории

На старте Wrapper‑файлы часто воспринимают как что‑то временное: «ну я же уже скачал Gradle, зачем хранить эти скрипты». И здесь важно поймать главную идею: Wrapper хранится в репозитории не потому, что вам лень поставить Gradle. Он хранится потому, что проект должен уметь запускаться сам по себе, без предварительных танцев.

В командной разработке проект живёт так: кто‑то клонирует Git‑репозиторий, открывает README и запускает команды. Если в проекте нет Wrapper, первая команда превращается в «сначала поставь Gradle нужной версии». А дальше начинаются уточнения: «а какую версию?», «а где скачать?», «а что если у меня уже стоит другая?», «а это точно ничего не ломает?».

Wrapper обрывает эту ветку вопросов на корню. Он говорит: «вот вход, вот версия, запускай». Именно поэтому Wrapper‑файлы должны быть закоммичены в Git вместе с кодом. И именно поэтому любые .gitignore, которые случайно игнорируют gradle-wrapper.jar или gradle-wrapper.properties, — это диверсия против воспроизводимости.

Важное уточнение: папка build/, которую Gradle создаёт при сборке, — это действительно генерируемый артефакт, его мы обычно не коммитим. А вот gradle/wrapper/ — это не «результат сборки», а часть описания того, как собирать. Воспринимайте это как инструкции к проекту, которые должны лежать рядом с самим проектом.

7. Схема запуска Wrapper

У новичка очень часто возникает внутренний дискомфорт: «я запускаю ./gradlew build, и где‑то там что‑то происходит, но я не понимаю что». И это нормальная эмоция. Мы сейчас не изучаем внутренности Gradle, но важно убрать ощущение чёрного ящика хотя бы на уровне общей схемы.

Вот упрощённая блок‑схема того, что происходит:

flowchart TD
    A["Вы в корне проекта запускаете ./gradlew build"] --> B["Скрипт gradlew / gradlew.bat"]
    B --> C["Wrapper (gradle-wrapper.jar)"]
    C --> D["Читает gradle-wrapper.properties и узнаёт версию Gradle"]
    D --> E{"Нужная версия Gradle уже скачана?"}
    E -->|Нет| F["Скачивает Gradle дистрибутив и кладёт в локальный кэш"]
    E -->|Да| G["Использует локальный кэш"]
    F --> H["Запускает Gradle нужной версии"]
    G --> H["Запускает Gradle нужной версии"]
    H --> I["Gradle выполняет задачу build/run по правилам проекта"]

Эта схема важна тем, что показывает: Wrapper не «заменяет Gradle». Он просто гарантирует, что Gradle будет правильной версии и что запуск всегда начинается одинаково.

И теперь можно аккуратно привязать это к нашему проекту. ReadLater Starter — это репозиторий, который должен запускаться одинаково у всех студентов. Поэтому мы будем везде — в README, в примерах команд и в собственных привычках — использовать только Wrapper‑команды. Это станет «правилом игры» проекта — таким же, как «Java‑код лежит в src/main/java», а не где попало.

8. Типичные ошибки при работе с Wrapper

Ошибка №1: запускать gradle build вместо ./gradlew build.
Это одна из самых частых путаниц. Команда gradle build обращается к Gradle, установленному в вашей системе (если он вообще установлен), и может иметь другую версию. В результате вы тратите время не на обучение и проект, а на угадывание, почему пример из лекции не совпадает с вашим выводом в консоли.

Ошибка №2: удалять или не коммитить Wrapper‑файлы, потому что они «служебные».
Кажется логичным «почистить проект» и убрать лишнее. Но Wrapper — это не мусор и не кэш. Это часть контракта репозитория: как именно этот проект должен запускаться. Если в репозитории нет Wrapper, у другого человека нет гарантированного способа воспроизвести ваш запуск.

Ошибка №3: путать gradlew и gradlew.bat и пытаться запускать не тот файл на своей ОС.
На macOS/Linux вы обычно запускаете ./gradlew. На Windowsgradlew.bat. Попытка запускать «не свой» скрипт часто заканчивается странными сообщениями: терминал не понимает формат файла, права не те, кодировка не та. Проще принять это как факт: есть два входа для двух семейств ОС.

Ошибка №4: запускать Wrapper не из корня проекта.
Команды ./gradlew ... имеют смысл, когда вы стоите в директории, где лежит файл gradlew. Если вы случайно ушли в src/main/java и пытаетесь запускать оттуда, то получите «No such file or directory» или аналогичное сообщение. Это не «Gradle не работает», а вы просто стоите не в той папке.

Ошибка №5: пугаться долгого первого запуска и принимать скачивание Gradle за сбой.
При первом запуске Wrapper действительно может скачать дистрибутив Gradle. Это нормальная механика, а не ошибка. Если интернет есть и ссылка в distributionUrl корректна, дальше всё будет работать быстрее за счёт кэша.

1
Задача
Java Server, 2 уровень, 1 лекция
Недоступна
Wrapper-файлы как часть репозитория
Wrapper-файлы как часть репозитория
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ