jamesfredley opened a new pull request, #15647: URL: https://github.com/apache/grails-core/pull/15647
## Summary PR #15646 was iteration 1 of fixing the Forge `dockerBuildNative` Cloud Run deploy failures. It moved the build past the original `ch.qos.logback.* was unintentionally initialized at build time` errors but introduced a second-order conflict: with our `--initialize-at-run-time=ch.qos.logback,org.slf4j` directive in place, the GraalVM Reachability Metadata Repository 1.4.9 entry's `--initialize-at-build-time=ch.qos.logback` directive started reporting the same logback classes as `the class was requested to be initialized at run time ... got initialized during image building` (see [run 25574400224](https://github.com/apache/grails-core/actions/runs/25574400224)). `--trace-class-initialization` showed the actual cascade source: ``` ch.qos.logback.core.CoreConstants the class was requested to be initialized at run time ... org.eclipse.jgit.transport.Transport caused initialization of this class with the following trace: at ch.qos.logback.core.CoreConstants.<clinit>(CoreConstants.java:48) ``` `org.eclipse.jgit.transport.Transport` (and most of the other `Transport*` classes) declares a `static final Logger LOG` field. Forcing them to `--initialize-at-build-time` in `grails-forge-api/native-image.properties` transitively runs `LoggerFactory.<clinit>` and the entire `ch.qos.logback` class graph at build time. This worked under logback 1.4.x because GRM 1.4.9 also marked `ch.qos.logback` as build-time, so they all got initialized together. Under logback 1.5.x the GRM entry is incomplete (additional 1.5.x classes are still expected at run time), and our explicit run-time override turns the cascade into a hard error. This PR resolves it with two coordinated changes that together let `dockerBuildNative` succeed end-to-end **locally** for both modules: ### 1. Drop the manual JGit build-time-init list [`grails-forge-api/.../native-image.properties`](https://github.com/apache/grails-core/blob/8.0.x/grails-forge/grails-forge-api/src/main/resources/META-INF/native-image/org.grails.forge.api/grails-forge-api/native-image.properties) used to force a long list of `org.eclipse.jgit.*` classes to `--initialize-at-build-time`. That list predates the GraalVM Reachability Metadata Repository entry for `org.eclipse.jgit:org.eclipse.jgit` (which now ships reflection and resource metadata covering jgit 6.5.0+ and our 6.10.x runtime). It is the cascade source for the logback build-time init and is no longer necessary - JGit can fall back to the default (run-time) class initialization. Only the existing `--initialize-at-run-time=org.eclipse.jgit.lib.internal.WorkQueue` entry remains (opposite direction, unrelated). ### 2. Pin the GRM repo zip version to 0.3.35 [`grails-forge-web-netty/build.gradle`](https://github.com/apache/grails-core/blob/8.0.x/grails-forge/grails-forge-web-netty/build.gradle) and [`grails-forge-analytics-postgres/build.gradle`](https://github.com/apache/grails-core/blob/8.0.x/grails-forge/grails-forge-analytics-postgres/build.gradle) now set `graalvmNative.metadataRepository.version = '0.3.35'`. The version bundled with the Micronaut Gradle Application Plugin 4.6.2 selects the `ch.qos.logback:logback-classic` 1.4.9 metadata for our 1.5.17 runtime, whose `--initialize-at-build-time=ch.qos.logback` directive forces the conflict regardless of the JGit cascade. GRM 0.3.35 (released 2026-03-06) ships a 1.5.7 metadata directory covering 1.5.7 - 1.5.29 (so it covers 1.5.17), and that directory contains only `reflect-config.json` and `resource-config.json` - no `--initialize-at-build-time` directive - so logback initializes at the default (run-time) and the existing `--initialize-at-run-time=ch.qos.logback,org.slf4j` overri de from PR #15646 applies unopposed. GRM `1.x` release zips use a new repository layout that the `GraalVMReachabilityMetadataService` bundled with the current plugin does not understand (`NoSuchFileException: .../exploded/index.json`), so we stay on the last compatible 0.3.x release with the updated logback metadata. ## Verification Reproduced locally on Docker 29.3.0 against the same `ghcr.io/graalvm/native-image-community:21.0.2-ol9` image used by the Forge deploy workflows: ``` $ ./gradlew :grails-forge-web-netty:dockerBuildNative -PdockerImageName=grails-forge-local:web-netty BUILD SUCCESSFUL in 2m 33s Successfully tagged grails-forge-local:web-netty $ docker run -d -p 18080:8080 grails-forge-local:web-netty $ docker logs <id> io.micronaut.runtime.Micronaut - Startup completed in 45ms. Server Running: http://...:8080 $ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:18080/ 200 $ ./gradlew :grails-forge-analytics-postgres:dockerBuildNative -PdockerImageName=grails-forge-local:analytics BUILD SUCCESSFUL in 3m 24s Successfully tagged grails-forge-local:analytics $ docker run -d -p 18081:8080 grails-forge-local:analytics # Native binary starts, reaches DB connection step (fails as expected without local Postgres): # Caused by: org.postgresql.util.PSQLException: Connection to localhost:5432 refused. ``` Class-initialization conflicts gone, native binaries actually start, postgres driver runtime path exercised. CI checks (CI, RAT, CodeQL, code-style, Groovy joint validation) cover the rest; the deploy workflows are `workflow_dispatch`-only and will be re-triggered after this lands. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
