Pular para conteúdo

0021 — Config de build native-image (Fase B)

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-14 · Decidido em: 2026-08-24

Continua a decisão 0020 (Fase A — POI→FastExcel, o bloqueio de biblioteca). Espelha a ADR central 0022 — native-image é o alvo de deploy. É a etapa de build do native, antes do deploy (o deploy native está na 0028).

Contexto

Com o POI fora do grafo (0020), o nativeCompile do plugin io.micronaut.application já roda — faltava só a configuração que a casa fixou: o perfil de build (otimização + GC) e o único hint de reflexão recorrente da frota (o SentryAppender do logback, instanciado pelo Joran).

Decisão

  1. Perfil GraalVM no build.gradle.kts. O accessor Kotlin DSL graalvmNative {} não é gerado (o plugin native-build-tools entra transitivo, não aplicado direto), então configura-se via configure<GraalVMExtension> + import org.graalvm.buildtools.gradle.dsl.GraalVMExtension:
  2. -PnativeQuick → -Ob (build ~40–60% mais rápido, binário maior/lento — loop de dev/e2e); sem a flag (prod) → -Os (menor imagem).
  3. --gc=serial — menor footprint de RAM; é o default da GraalVM CE, explicitado.
  4. A CE 25 não tem --gc=G1, PGO nem --emit build-report (Oracle-GraalVM-only), e -O3 em CE equivale a -O2 — nada a prometer de -O3.

  5. reflect-config.json local em src/main/resources/META-INF/native-image/br.com.onpetro/bi-comercial-xls/, registrando io.sentry.logback.SentryAppender por nome-como-string (não Class.class — evita o javac carregar a classe do Sentry, que arrasta org.jetbrains.annotations.Nullable ausente do classpath). É o único hint manual recorrente da casa, confirmado byte-idêntico em múltiplos apps native.

Consequências

  • nativeCompile verde é o gate do repo do app. O runtime (boot/Flyway/POST) é o e2e native, em repo separado (0022) — não replicado aqui.
  • Deploy segue JVM durante a migração (defer explícito, REGRA Nº 3). A topologia da 0022 manda o Dockerfile do repo continuar JVM (dockerfile-java, shadowJar); a imagem native é buildada na fábrica de imagens (outro repo). Por isso docs/app.json "native": true e o dockerfile-java-native ficam para a T7, não entram aqui — setar native:true agora mentiria o discriminador ("deploya native") que o gate do ci.yml lê.
  • A hint do Sentry é dívida de repo de lib. O ideal é subir pra reachability-metadata da xadm-comum-web (dona do SentryInitializer) e sumir a cópia local em toda a frota; o jar 0.5.0 ainda não a traz (verificado). Enquanto isso, a cópia local é o caminho.

Correção 2026-09-11: o reflect-config.json local do item 2 não existe mais. A hint do SentryAppender vem da xadm-comum-web 0.9.1, que embarca META-INF/native-image/br.com.xadm/xadm-comum-web/reflect-config.json com as mesmas três entradas (SentryAppender e SentryOptions com construtor e allPublicMethods, e Level.valueOf), e o native-image o descobre no classpath. A dívida de lib das Consequências está fechada.

O deploy native deferido para a T7 está em vigor, e o native é o alvo único do build.targets: decisão 0028.

Alternativas descartadas

  • graalvmNative {} (accessor direto): não compila — o plugin é transitivo, o accessor não é gerado. configure<GraalVMExtension> é o caminho.
  • Setar native:true + Dockerfile native já (T7): premature — abre o gate de deploy native com a fábrica/e2e ainda pendentes (B2/B3/B4). Deferido para T7 (REGRA Nº 3).

Correção 2026-09-14: o andaime .ia/012 saiu do repo depois de destilado; o ponteiro passou para a decisão 0028.