Нативная сборка GraalVM
Обычный jar запускается на JVM: виртуальная машина загружает классы, а JIT-компилятор переводит горячий код в машинный уже во время работы. Нативный образ (native image) устроен иначе: инструмент native-image из GraalVM заранее компилирует приложение вместе с нужной частью JDK в обычный исполняемый файл для конкретной ОС — как программу на C. Такой файл запускается без установленной Java, за десятки миллисекунд, и расходует заметно меньше памяти.
Почему Micronaut подходит
При сборке нативного образа GraalVM исходит из «закрытого мира»: всё, что приложение может вызвать, должно быть известно заранее. Рефлексия, динамические прокси и загрузка классов по имени ломают этот подход — для них приходится вручную писать файлы настроек. Micronaut почти не пользуется рефлексией: бины, маршруты, сериализация и запросы Micronaut Data уже сгенерированы при компиляции. Поэтому большинство приложений Micronaut собирается в нативный образ без дополнительной настройки.
Что нужно
- GraalVM для Java 25 вместо обычного JDK. Проще всего поставить через SDKMAN:
sdk install java 25.4.4+1-graal, затемsdk use java 25.4.4+1-graal. - Компилятор C для вашей ОС: в Linux —
gccи библиотеки разработчика, в Windows — Visual Studio Build Tools, в macOS — Xcode Command Line Tools. - Несколько гигабайт свободной памяти: сборка тяжёлая.
Сборка
Проект от генератора уже готов — плагин native-maven-plugin подключён через micronaut-parent. Достаточно сменить тип упаковки:
./mvnw package -Dpackaging=native-imageСборка занимает несколько минут. Результат — файл target/blog (в Windows target\blog.exe). Его запускают напрямую, без java:
./target/blogПриложение отвечает на те же адреса и читает те же переменные окружения, что и jar. Есть и вариант сразу в контейнер: ./mvnw package -Dpackaging=docker-native.
Jar или нативный файл
| Исполняемый jar | Нативный образ | |
|---|---|---|
| Нужна Java на сервере | да | нет |
| Время сборки | секунды | минуты |
| Запуск | около секунды | десятки миллисекунд |
| Память | больше | меньше |
| Один файл для всех ОС | да | нет, собирается под каждую ОС |
| Пиковая скорость долгой работы | высокая благодаря JIT | обычно чуть ниже |
Нативный образ выгоден там, где приложение часто запускают и останавливают: функции в облаке (serverless), автомасштабирование в Kubernetes, утилиты командной строки. Для обычного долго работающего сервиса исполняемый jar проще и вполне хорош.
Как проверять
Перед нативной сборкой убедитесь, что тесты проходят на JVM. Библиотеки, которые используют рефлексию, могут потребовать подсказок для GraalVM — их пишут в src/main/resources/META-INF/native-image/. Для своих классов в Micronaut обычно хватает @Serdeable и @Introspected.
Частая ошибка
Если запустить нативную сборку на обычном JDK, Maven остановится на шаге native:compile-no-fork:
[ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:1.1.12:compile-no-fork (default-compile-no-fork)
on project blog: native-image is not installed in your JAVA_HOME. This probably means that the JDK at '...' is not
a GraalVM distribution. The GraalVM Native Maven Plugin requires GRAALVM_HOME or JAVA_HOME to be a GraalVM distribution.Установите GraalVM и укажите путь к нему в JAVA_HOME или GRAALVM_HOME, затем проверьте командой native-image --version.