Product3 MIN READ129 / 129

Native builds

Status: implemented GraalVM native build for the current JVM service. Updated: 29 October 2026.

Build and run

cd apps/product-backend
./mvnw -Pnative native:compile
./target/product-backend --server.port=8080
curl http://127.0.0.1:8080/hello

./mvnw -Pnative native:compile runs Spring AOT and GraalVM native compilation. ./mvnw package alone does not prove a native executable was built.

The result is a native executable for the current operating system and architecture. Cross-platform releases must be built on the target platform. Native compilation can take several minutes and substantial memory.

Build configuration

  • The Spring Boot parent supplies the native profile, AOT execution, and reachability-metadata integration.
  • The explicit ProductBackendApplicationKt main class preserves Kotlin’s top-level entry point.
  • The Kotlin Spring compiler plugin supports Spring proxies.
  • META-INF/native-image/com.astrology/product-backend/native-image.properties enables HTTP and HTTPS URL protocols for outbound calls.
  • AOT discovers the controllers and configuration classes; no handwritten reflection registry is needed for them.
  • SecurityConfiguration registers the JWT authentication provider directly, so Spring builds its authentication manager without the lazy fallback proxy. No custom security runtime-hint registrar is needed.

Nested access/refresh duration settings use plain @NestedConfigurationProperty so Spring AOT discovers their constructor binding metadata. They require no handwritten runtime-hint registrar.

Reflection registration

NativeReflectionConfiguration registers all eight product entities with @RegisterReflectionForBinding for native JSON binding:

  • AppUser
  • Profile
  • LoginIdentity
  • LoginSession
  • Subscription
  • SubscriptionTracking
  • RedeemCode
  • RedeemCodeTracking

Jackson’s Kotlin module is a production dependency, so Boot’s configured JsonMapper can deserialize their Kotlin constructors. Explicit JDBC row mappers remain independent of JSON reflection.

The login DTOs are registered separately on LoginController with @RegisterReflectionForBinding. Keep that registration when changing request or response DTOs.

NativeReflectionConfiguration does not register migration resources. Schema installation belongs to operators and tests; Flyway remains a test-only dependency.

Tests

Run the JVM tests first. Docker must be running because the HTTP integration tests start a disposable PostgreSQL container:

./mvnw verify
./mvnw -Dtest=ProductEntityDtoIntegrationTests test

verify includes the Google decoder, token decoder, HTTP login, and entity JSON tests. The entity JSON integration tests load Boot’s Jackson auto-configuration and the native registration without a datasource or HTTP infrastructure. They cover exact JSON fields, 64-bit numeric IDs, timestamp precision, nullable values, enum serialization, round trips, and the registration list.

Compile and execute the selected tests in a GraalVM native image:

./mvnw clean -PnativeTest -Dtest=ProductEntityDtoIntegrationTests test

A JVM pass alone does not establish native compatibility. The native test profile also AOT-processes discovered Spring test contexts, so unrelated application-context configuration can still block that build.

Limitations

  • Native builds do not deploy anything or create Cloudflare resources.
  • Production uses direct JDBC access to Supabase PostgreSQL; remote deployment is not configured here.
  • Native artifacts are platform-specific.
  • Add narrowly scoped runtime hints only when a new integration demonstrates dynamic access, then exercise that path in the native executable.
  • Flyway is a test-only dependency and does not run in the native runtime.
Path Owns
pom.xml Spring Boot parent, Kotlin plugin, entry point, and Native Build Tools.
src/main/kotlin/com/astrology/product/ProductBackendApplication.kt Kotlin entry point and component scan.
src/main/kotlin/com/astrology/product/platform/config/NativeReflectionConfiguration.kt Entity JSON reflection registration.
src/main/kotlin/com/astrology/product/account/login/LoginController.kt Login DTO reflection registration.
src/main/resources/META-INF/native-image/com.astrology/product-backend/native-image.properties URL protocol configuration.
src/test/kotlin/com/astrology/product/integration/ProductEntityDtoIntegrationTests.kt Entity JSON and registration tests.
src/test/kotlin/com/astrology/product/integration/LoginHttpIntegrationTests.kt HTTP, security, and JDBC login tests.