jamesfredley opened a new pull request, #15646:
URL: https://github.com/apache/grails-core/pull/15646

   ## Summary
   
   Both `grails-forge` Cloud Run deploy workflows ([Forge - Next GCP Deploy run 
25514779324](https://github.com/apache/grails-core/actions/runs/25514779324) 
and [Forge - Prev Snapshot GCP Deploy run 
25515077555](https://github.com/apache/grails-core/actions/runs/25515077555)) 
are currently failing at the `dockerBuildNative` step with GraalVM "*was 
unintentionally initialized at build time*" errors. This PR fixes the two 
distinct class-initialization conflicts that surface during native-image 
analysis.
   
   ## Root cause
   
   ### `grails-forge-web-netty:dockerBuildNative`
   
   The Micronaut Gradle Application Plugin 4.6.2 transitively bundles the 
GraalVM Reachability Metadata Repository entry for 
`ch.qos.logback/logback-classic` at metadata-version **1.4.9** (visible in the 
build log as `config-dirs/ch.qos.logback/logback-classic/1.4.9`). That entry 
marks the entire `ch.qos.logback` package as `--initialize-at-build-time`, but 
the directive is incomplete for **logback 1.5.x**, which is what we ship 
(`logbackClassicVersion=1.5.17`, `slf4jVersion=2.0.17`). During native-image 
analysis, additional 1.5.x classes (`StatusBase`, `Token`, `JoranConstants`, 
`StatusPrinter`, `LogbackClassicDefaultNestedComponentRules`, 
`ImplicitModelHandler$1`, `NodeToStringTransformer$1`, 
`org.slf4j.LoggerFactory`, `CoreConstants`, `Parser`, `Level`, `InfoStatus`, 
`PropertySetter$1`, `ChainedModelFilter$1`, `Parser$1`, `pattern.parser.Parser` 
...) get reached and reported as "unintentionally initialized at build time".
   
   The official GRM repo already publishes a 1.5.7 metadata entry that covers 
logback 1.5.7 through 1.5.29 - the Micronaut Gradle plugin we use just doesn't 
pull it yet.
   
   ### `grails-forge-analytics-postgres:dockerBuildNative`
   
   The `Args = 
--initialize-at-build-time=org.postgresql.Driver,org.postgresql.util.SharedTimer`
 line in `native-image.properties` forced `org.postgresql.Driver` to initialize 
at build time, which transitively triggered `java.sql.DriverManager.<clinit>` 
to run at build time. Micronaut SQL registers `java.sql.DriverManager` for 
run-time initialization, producing the conflict reported as 
`java.sql.DriverManager was unintentionally initialized at build time`.
   
   This manual override is also no longer needed: PostgreSQL **42.7.5** (the 
version we ship via `postgresqlVersion=42.7.5`) is officially covered by the 
GraalVM Reachability Metadata Repository (metadata-version 42.7.3, tested 
through 42.7.11), and `micronaut-jdbc` already ships 
`--add-modules=java.sql.rowset` for the rest of the JDBC support classes.
   
   ## Changes
   
   ### `grails-forge-web-netty/.../native-image.properties`
   
   Add `--initialize-at-run-time=ch.qos.logback,org.slf4j` to override the 
bundled 1.4.9 build-time-init directive without touching reflection or resource 
configuration.
   
   ```properties
   Args = -H:Name=grails-forge \
          -H:Class=org.grails.forge.netty.Application \
          --initialize-at-run-time=ch.qos.logback,org.slf4j
   ```
   
   ### `grails-forge-analytics-postgres/.../native-image.properties`
   
   Drop the manual 
`--initialize-at-build-time=org.postgresql.Driver,org.postgresql.util.SharedTimer`
 and replace with the same logback runtime-init override (this module also has 
`runtimeOnly "ch.qos.logback:logback-classic:$logbackClassicVersion"`, so it 
will hit the same logback issue once the DriverManager error clears).
   
   ```properties
   Args = --initialize-at-run-time=ch.qos.logback,org.slf4j
   ```
   
   Both files are now header-commented to explain why these flags exist, 
matching the style used in the `dockerfileNative` block in 
`grails-forge-web-netty/build.gradle` and 
`grails-forge-analytics-postgres/build.gradle` for the GraalVM image pin.
   
   ## Verification
   
   - `./gradlew :grails-forge-web-netty:processResources 
:grails-forge-analytics-postgres:processResources` (offline) → exit 0; both 
`native-image.properties` files load via `java.util.Properties.load(...)` and 
produce the expected `Args` value.
   - The native-image analysis itself runs in the GraalVM Community 21.0.2 
container during `dockerBuildNative` and is best verified by re-triggering the 
two `workflow_dispatch` workflows after this lands. RAT, code-style and the 
standard `gradle.yml` build are unaffected because the changes are confined to 
`META-INF/native-image/**/native-image.properties`, which is excluded from RAT 
(see `gradle/rat-root-config.gradle`).
   
   ## References
   
   - GraalVM Reachability Metadata Repository entry for ch.qos.logback (1.5.7 
metadata covers 1.5.7 - 1.5.29): 
https://github.com/oracle/graalvm-reachability-metadata/tree/master/metadata/ch.qos.logback/logback-classic
   - GraalVM Reachability Metadata Repository entry for org.postgresql (42.7.3 
metadata covers 42.7.3 - 42.7.11): 
https://github.com/oracle/graalvm-reachability-metadata/tree/master/metadata/org.postgresql/postgresql
   - GraalVM Class Initialization reference: 
https://www.graalvm.org/latest/docs/reference-manual/native-image/optimizations-and-performance/ClassInitialization/
   


-- 
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]

Reply via email to