JavaRush /Курси /Spring Boot /Gradle Wrapper, Toolchain і плагін Spring Boot

Gradle Wrapper, Toolchain і плагін Spring Boot

Spring Boot
Рівень 3 , Лекція 1
Відкрита

1. Збирання як частина застосунку

Якщо ви щойно прийшли зі світу консольних програм, збирання може здаватися чимось на кшталт «Ну це ж просто натиснути Run». Але щойно у проєкті зʼявляється бодай один колега — або другий компʼютер, — починається класичний серіал: «У мене працює, у вас — ні, давайте зідзвонимося, покажіть екран». Spring Boot як платформа любить передбачуваність, а отже, потребує й передбачуваного збирання.

Каркас проєкту вже є, але без чітких правил збирання він лишається просто набором файлів. Після генерації головне питання стає дуже практичним: як зробити так, щоб цей каркас однаково збирався і запускався на будь-якій машині.

Уявіть, що catalog-service — це страва. Код — інгредієнти, Spring-контейнер — кухня, а збирання — рецепт із температурою, часом і точними пропорціями. Якщо рецепт «приблизний», то на одній плиті все вийде нормально, а на іншій — суцільне вугілля. Тому на старті ми фіксуємо три речі: який Gradle використовується, яка Java використовується і які Boot-завдання доступні в проєкті.

Щоб не плутати терміни, тримайте в голові просту таблицю — вона сильно економить нерви:

Річ Що фіксує Де живе Як її запускати / використовувати
Gradle Wrapper Версію Gradle У репозиторії проєкту ./gradlew ...
Java Toolchain Версію Java для компіляції та завдань Gradle build.gradle.kts Gradle застосовує автоматично
Boot plugin Boot-орієнтовані завдання та домовленості build.gradle.kts bootRun,
bootJar
та ін.

Ці три точки потім сходяться в одному місці — у build.gradle.kts. Тому корисно спочатку зрозуміти їхні ролі окремо, а вже потім читати build-файл цілком. Саме тому зараз важливо не стільки тиснути Run, скільки зрозуміти, на чому цей запуск узагалі тримається.

2. Gradle Wrapper: «Gradle, що приходить разом із проєктом»

В ідеальному світі в усіх стоїть однаковий Gradle, однакова Java й однакова удача. У реальному світі в кожного розробника на ноутбуці свій «зоопарк»: у когось Gradle 8, у когось 9.4, хтось узагалі ніколи його не ставив, бо «у мене IntelliJ сам усе вміє». Gradle Wrapper — це спосіб зробити проєкт незалежним від цих випадковостей.

Wrapper — це не окрема програма замість Gradle. Це набір файлів у вашому проєкті, який гарантує: коли ви запускаєте збирання, ви запускаєте потрібну версію Gradle, вибрану самим проєктом. І так, це одна з причин, чому в Boot-проєктах у README пишуть команди саме з ./gradlew, а не просто gradle.

Коли ви генеруєте проєкт в Initializr, він додає Wrapper автоматично — і це чудово, бо руками новачок майже завжди щось забуде, а потім казатиме: «У мене Gradle зламався», хоча насправді його… не було.

Мінікарта файлів Wrapper виглядає так:

catalog-service/
├── gradlew
├── gradlew.bat
└── gradle/
    └── wrapper/
        ├── gradle-wrapper.properties
        └── gradle-wrapper.jar

Тут важливо без містики розуміти роль кожного файлу. gradlew — скрипт для Linux/macOS, gradlew.bat — для Windows. Їхнє завдання просте: взяти налаштування з gradle-wrapper.properties, завантажити потрібний Gradle, якщо його ще немає в кеші, і запустити збирання. gradle-wrapper.jar — маленький «двигун» Wrapper, який уміє завантажувати й запускати правильну версію Gradle.

Якщо ви думаєте: «А можна видалити gradle-wrapper.jar? Він же бінарник, дивно зберігати його в Git?» — можна, але тоді ви повернетеся в камʼяний вік: кожен запускатиме збирання як вийде. Ми так не робимо. Ми хочемо, щоб catalog-service був переносним.

Як Wrapper вибирає Gradle

Найцікавіший файл тут — gradle/wrapper/gradle-wrapper.properties. Він маленький, але саме він відповідає за те, яку версію Gradle ваш проєкт вважає «правильною».

Типовий приклад:

# Звідки Wrapper завантажує дистрибутив Gradle
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4-bin.zip

Зверніть увагу на просту думку: версія Gradle — це не «що у вас установлено», а «що написано в проєкті». Під час першого запуску Wrapper завантажить зазначений дистрибутив Gradle й покладе його в кеш користувача, зазвичай десь у домашньому каталозі, всередині ~/.gradle/.... Тому перший запуск може бути трохи довшим: це нормально, ви не зламали інтернет.

Корисно заздалегідь знати, де живе кеш, щоб не панікувати, коли Gradle «щось довго завантажує». У спрощеному вигляді картина така:

flowchart TD
    A[Ви запускаєте ./gradlew] --> B[Wrapper читає gradle-wrapper.properties]
    B --> C{Потрібна версія Gradle вже в кеші?}
    C -- Так --> D[Запуск Gradle]
    C -- Ні --> E[Завантаження gradle-9.4-bin.zip]
    E --> F[Розпакування в ~/.gradle/wrapper/dists]
    F --> D[Запуск Gradle]

Це і є відтворюваність: один і той самий проєкт завжди тягне одну й ту саму версію Gradle, і збирання поводиться передбачувано.

Правильний запуск Wrapper із кореня

Wrapper запускається командами, які виглядають однаково на всіх машинах, але з невеликою відмінністю залежно від ОС. Важливе правило — запускати їх з кореня проєкту, там, де лежить gradlew. Інакше Gradle може не знайти ваш build.gradle.kts, settings.gradle.kts і взагалі поводитиметься так, ніби ви прийшли не на ту вечірку.

Мінімальний набір команд, який варто запамʼятати вже зараз:

# Linux/macOS
./gradlew --version

# Windows (cmd)
gradlew.bat --version

# Windows (PowerShell)
.\gradlew --version

Зверніть увагу: ./gradlew — це не «якась магічна крапка і слеш». Це буквально «запусти файл gradlew із поточної папки». Якщо ви випадково напишете просто gradle, то запустите глобально встановлений Gradle, якщо він у вас є, і вся ідея Wrapper буде знищена одним натисканням Enter. Тож так, ./gradlew — наш маленький щоденний ритуал, який рятує від великих щоденних проблем.

3. Java Toolchain: фіксуємо версію Java

Друга класична проблема новачка: «Я встановив Java, але проєкт усе одно не збирається» або «У мене Java 25, а Gradle пише, що потрібна 21». І тут важливо зрозуміти: насправді у вас може бути кілька Java одночасно, і це не помилка, а нормальний стан розробки. Проблема починається, коли проєкт не говорить явно, яку саме Java він очікує.

Java Toolchain — це механізм Gradle, який дозволяє в build.gradle.kts явно сказати: «компілюй проєкт ось цією версією Java». І тоді збирання перестає залежати від того, яка Java випадково опинилася першою в PATH або яку Java IDE підхопила за замовчуванням.

Тут важливо триматися однієї лінії: у проєкту не повинна раптом зʼявитися друга «справжня» версія Java. Якщо в Initializr вибрано Java 25, ту саму версію фіксуємо й у toolchain. Тоді в проєкту не буде окремої «формальної» Java у формі та окремої «реальної» Java в збиранні.

Мінімальне налаштування toolchain у build.gradle.kts

Toolchain налаштовується в build.gradle.kts у блоці java. Це виглядає спокійно й не потребує магії:

java {
    toolchain {
        // Явно фіксуємо версію JDK для збирання, компіляції та Gradle-завдань
        languageVersion = JavaLanguageVersion.of(25)
    }
}

Що це означає по-людськи: «Gradle, коли компілюватимеш і виконуватимеш завдання, використовуй JDK 25 як цільову». При цьому у вас на машині може бути і JDK 17, і 21, і 25, але збирання намагатиметься використовувати саме те, що ви вказали.

Важливо не плутати це з тим, на якій Java запускається сам Gradle. Gradle теж працює всередині JVM. Якщо у вас стоїть зовсім не та Java для запуску Gradle, ви можете отримати помилку ще до того, як toolchain почне працювати. Це рідкість, але якщо раптом так сталося — не треба панікувати: це не «Spring зламався», а просто «Gradle не зміг стартувати на цій JVM».

Перевірка застосування toolchain

Новачки часто налаштовують toolchain, а потім не розуміють: «Воно взагалі спрацювало чи я просто красиво написав шматок тексту в build.gradle.kts?» Гарна новина: перевірка існує, і вона не потребує філософії.

По-перше, можна подивитися, яку Java бачить Gradle і на якій він узагалі запустився:

./gradlew --version

По-друге, у Gradle є звіт про toolchains, який часто доступний як завдання javaToolchains. Це зручний спосіб побачити, які JDK знайдено і яка буде вибрана:

./gradlew -q javaToolchains

Якщо завдання недоступне, це не катастрофа: тоді достатньо ./gradlew --version і перевірки налаштувань IDE. Але коли javaToolchains є, це прямо «рентген» вашої Java-частини збирання.

Тут корисно тримати просту думку: toolchain — це про збирання, а не про те, що ви випадково бачите в терміналі після java -version. Термінал показує Java, яку бачить поточна сесія, а Gradle toolchain — Java, вибрану проєктом.

4. Плагін org.springframework.boot: роль у збиранні

Якщо Wrapper і toolchain відповідають за відтворюваність збирання, то Boot plugin відповідає за те, щоб воно було Spring Boot-орієнтованим. Можна зібрати Java-проєкт і без Boot plugin. Можна навіть зібрати вебзастосунок і без нього, якщо дуже хочеться страждати. Але ми тут навчаємося не страждати, а будувати правильний базис.

Boot plugin — це не «ще одна залежність». Це розширення Gradle, яке додає зручні завдання й домовленості саме для Boot-застосунків: запуск через bootRun, збирання виконуваного jar через bootJar, правильне пакування, зрозумілі дефолти. Ви ніби кажете Gradle: «Це не просто Java-програма. Це Spring Boot-застосунок, тож поводься з ним відповідно».

Підключаємо Boot plugin і фіксуємо версію Boot

Плагіни підключаються в блоці plugins у build.gradle.kts. Мінімально це виглядає так:

plugins {
    // Базові завдання Java-проєкту: компіляція, тести, збирання jar
    java

    // Spring Boot-завдання та домовленості: bootRun, bootJar тощо
    id("org.springframework.boot") version "4.0.3"
}

Сенс простий: java каже Gradle «це Java-проєкт, увімкни компіляцію, тести й стандартні завдання», а org.springframework.boot додає поверх цього Boot-специфіку. Версія плагіна зазвичай збігається з версією Spring Boot, яку ви вибрали в Initializr.

І важлива практична думка: не треба підкручувати версію Boot навмання. Якщо ви раптом зміните 4.0.3 на щось на кшталт 4.0.99-rc1, бо «хочу найновіше», то отримаєте пригоди. А пригоди нам у цьому курсі потрібні лише у вигляді розуміння, а не у вигляді багів.

Що додає Boot plugin

Часто здається, що плагін — це щось абстрактне. Тому давайте закріпимо максимально предметно: Boot plugin додає завдання Gradle, якими ви реально користуватиметеся.

Завдання Для чого потрібно Що ви отримаєте в підсумку
bootRun Запуск Boot-застосунку з вихідних текстів Застосунок стартує без ручного java -cp ...
bootJar Збирання виконуваного Boot jar Готовий артефакт, який можна запускати
test Запуск тестів Перевірка, що проєкт принаймні збирається і тести проходять

Як побачити, що завдання існує, не запускаючи його? Наприклад, так:

./gradlew help --task bootRun

Якщо Gradle описав вам завдання bootRun, отже, Boot plugin підключено і він працює. Це дуже спокійна, «безстресова» перевірка: ви нічого не збираєте, нічого не запускаєте, а просто питаєте в Gradle: «А в нас узагалі є така кнопка?»

5. Загальна схема базового збирання

На початку шляху легко сприймати gradlew, toolchain і Boot plugin як три розрізнені заклинання. Але це, по суті, одна історія: зробити збирання передбачуваним. Корисно побачити весь конвеєр цілком, інакше ви будете виправляти помилки навмання й казати знамените: «Я нічого не змінював, воно саме».

Спробуймо зібрати це в одну схему, як в інженерних документах:

flowchart TD
    Dev[Розробник] -->|запускає| W["./gradlew"]
    W --> G[Gradle 9.4 з Wrapper]
    G --> P[Плагіни: java + org.springframework.boot]
    P --> T[Завдання: compileJava / test / bootRun / bootJar]
    T --> A[Запуск або збирання catalog-service]

Тут усе чесно й без містики. Ви запускаєте ./gradlew — це вхід у збирання. Wrapper забезпечує версію Gradle. Gradle читає build.gradle.kts, підключає плагіни. Плагіни додають завдання. Завдання або запускають застосунок (bootRun), або збирають артефакт (bootJar). І лише після цього зʼявляється щось, що можна назвати «працюючим застосунком».

Якщо запамʼятати цей ланцюжок, половина ранніх проблем зникає сама собою: ви розумієте, на якому кроці «зламалося», і перестаєте лагодити все підряд.

Мініперевірка базового контуру в catalog-service

Дуже хочеться одразу натиснути Run і побачити «Started CatalogServiceApplication…». Це нормально, ми всі такі. Але хороший інженерний старт — спочатку переконатися, що інструменти на місці, а вже потім запускати застосунок. Тут ми зробимо невелику перевірку: вона займає кілька хвилин і економить години.

Перша команда перевіряє, що Wrapper працює і Gradle запускається через проєкт:

./gradlew --version

Друга команда корисна саме для теми сьогоднішньої лекції: ви побачите, які Java toolchains доступні, або принаймні переконаєтеся, що Gradle нормально бачить вашу Java:

./gradlew -q javaToolchains

Третя команда перевіряє Boot plugin без ризику: ми не стартуємо сервер і нічого зайвого не завантажуємо — просто дивимося, що завдання є:

./gradlew help --task bootRun

Якщо всі три команди відпрацювали без помилок, ви в дуже хорошій позиції. У вас є відтворюване збирання, зафіксована Java-ціль і Boot-орієнтовані завдання. Це і є базова гігієна збирання проєкту.

6. Типові помилки

Майже всі проблеми з Wrapper, toolchain і плагінами виникають не тому, що ви «щось не зрозуміли», а тому, що в усіх нас є звички з інших світів розробки. Хтось звик, що «IDE сама все збере», хтось — що java -version показує істину, хтось — що «зайві файли можна видалити». Розберімо найчастіші граблі, щоб ви впізнавали їх із першого погляду.

Помилка №1: запускати gradle замість ./gradlew.
Якщо ви запускаєте глобальний gradle, ви виходите за межі відтворюваності. У вас може бути Gradle іншої версії, і ви отримаєте дивні помилки: від несумісності плагінів до «чому в мене немає bootRun». Лікується дуже просто: у проєктах курсу завжди починаємо команди з ./gradlew (або .\gradlew у PowerShell).

Помилка №2: запускати Wrapper не з кореня проєкту.
Коли ви запускаєте команди з іншої папки, Gradle може не знайти build.gradle.kts і settings.gradle.kts або знайде «не той проєкт». Симптоми бувають кумедні: від «Task not found» до відчуття, що Gradle «не бачить залежності». Звичка проста: спочатку cd catalog-service, потім ./gradlew ....

Помилка №3: видаляти файли Wrapper, бо «сміття» або «бінарники в Git — погано».
gradlew, gradlew.bat, gradle-wrapper.jar, gradle-wrapper.properties — це не сміття, а частина проєкту. Якщо їх видалити, ви перетворюєте збирання на лотерею. У навчальному проєкті ми хочемо, щоб будь-яка людина могла клонувати репозиторій і зібрати його без ручного встановлення «правильного Gradle».

Помилка №4: плутати «Java в терміналі» і «Java, яку використовує збирання».
Команда java -version показує, яка Java перша в PATH у вашому поточному терміналі. Але Gradle toolchain може вибирати іншу Java. Це не баг і не змова — якраз навпаки, це механізм контролю. Якщо ви бачите невідповідність, не лякайтеся: перевіряйте ./gradlew --version і, якщо доступно, javaToolchains.

Помилка №5: не фіксувати Java Toolchain і сподіватися на удачу IDE.
Сьогодні воно зібралося, завтра ви оновили IDE, післязавтра в колеги інший JDK — і все поїхало. Toolchain потрібен не тому, що ви «не довіряєте собі», а тому, що проєкт повинен мати чіткий контракт щодо Java. Для Boot-проєкту це базова гігієна, як мити руки перед готуванням.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ