Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Нативная сборка

Обычное Java-приложение запускается на JVM: виртуальная машина загружает классы, прогревается и только потом работает быстро. Нативная сборка (native image) превращает приложение в обычный исполняемый файл для конкретной операционной системы — как программа на C или Go. JVM для запуска не нужна. Такую сборку делает инструмент native-image из GraalVM или его сборки для Quarkus — Mandrel. Quarkus изначально проектировали под нативную сборку, поэтому для большинства расширений она работает без доработок.

Jar или нативный файл

Jar на JVMНативный файл
СтартСекундыДесятки миллисекунд
Память после стартаСотни МБДесятки МБ
Время сборкиДесятки секундНесколько минут
Пиковая скорость под нагрузкойВыше благодаря JITОбычно ниже
ЗапускНужна JavaНужен только файл

Нативный файл выгоден там, где сервис часто запускается и останавливается: serverless-функции, автомасштабирование в Kubernetes, маленькие контейнеры. Для долго работающего сервиса под постоянной нагрузкой обычный jar не хуже, а часто лучше.

Сборка с установленной GraalVM

Установите GraalVM для Java 25 (или Mandrel) и укажите путь к ней в переменной GRAALVM_HOME. В pom.xml генератор уже добавил профиль native, поэтому команда короткая:

./mvnw package -Dnative

Сборка идёт несколько минут и требует много памяти — лучше 8 ГБ свободной оперативной памяти. Результат — файл target/blog-1.0.0-SNAPSHOT-runner (в Windows — с расширением .exe), который запускается напрямую:

./target/blog-1.0.0-SNAPSHOT-runner

В строке запуска вместо on JVM будет native, а время старта — в миллисекундах.

Сборка в контейнере

Если GraalVM ставить не хочется, но есть Docker или Podman, Quarkus соберёт файл внутри контейнера с Mandrel:

./mvnw package -Dnative -Dquarkus.native.container-build=true

Учтите: так получается исполняемый файл для Linux. Он подходит для Docker-образа (следующий урок), но не запустится напрямую в Windows или macOS.

Ограничения

native-image заранее анализирует, какой код достижим, и выбрасывает остальное. Поэтому то, что Java обычно делает во время работы, в нативном файле требует подсказок:

  • Рефлексия. Классы, которые создаются или читаются через рефлексию в вашем коде, помечают @RegisterForReflection. Сущности, ресурсы и записи для JSON Quarkus регистрирует сам.
  • Ресурсы. Файлы из src/main/resources, которые читаются вручную, перечисляют в quarkus.native.resources.includes.
  • Библиотеки. Используйте расширения Quarkus вместо «голых» библиотек: расширение уже содержит нужные настройки для нативной сборки.

Нативную сборку проверяют тестами с @QuarkusIntegrationTest: генератор создавал GreetingResourceIT, и по его образцу можно сделать PostResourceIT extends PostResourceTest. Команда ./mvnw verify -Dnative соберёт файл и прогонит тесты прямо против него.

Частая ошибка

Если запустить -Dnative без GraalVM, сборка падает в самом конце:

[ERROR] Failed to execute goal io.quarkus.platform:quarkus-maven-plugin:3.40.1:build (default-build) on project blog:
Failed to build quarkus application: ... Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception:
java.lang.RuntimeException: Cannot find the `native-image.cmd` in the GRAALVM_HOME, JAVA_HOME and System PATH.

Это сообщение из Windows, где инструмент называется native-image.cmd. Установите GraalVM или Mandrel и задайте GRAALVM_HOME либо соберите в контейнере с -Dquarkus.native.container-build=true. В Windows для native-image дополнительно нужны инструменты сборки Visual Studio.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.