maczikasz opened a new issue, #16131:
URL: https://github.com/apache/grails-core/issues/16131

   
   ## Summary
   
   `GroovyPageCompiler` bakes the `.gsp` source file's modification time into 
every generated page
   class as a `static final long LAST_MODIFIED` constant. Because a fresh 
checkout gives each `.gsp`
   a new mtime, identical sources compiled on two machines produce different 
bytes. Any jar bundling
   precompiled GSPs therefore changes on every checkout, and Gradle's build 
cache cannot reuse
   anything downstream of it.
   
   The effect is invisible in the sense that matters: builds succeed and output 
is correct. They are
   just slower, on every fresh clone and every CI run.
   
   ## Why it is not hidden by classpath normalization
   
   Gradle's `COMPILE_CLASSPATH` normalization hashes only the ABI and ignores 
everything else. A
   `static final` constant is part of the ABI — constants are inlined into 
callers — so consumers
   re-key even under that mode. Archive-level reproducibility does not help 
either: the jars already
   use normalized entry timestamps (`1980-02-01`), and the divergence is inside 
the class bytes.
   
   ## Evidence
   
   Two CI builds of this project at the same commit (`01037bdf`), on the ASF 
Develocity instance:
   
   https://develocity.apache.org/c/kat5373gl55fw/lenhcqeavcokm/task-inputs
   
   For `:grails-fields:jar` and `:grails-spring-security:jar`, `compileGroovy`, 
`compileJava` and
   `processResources` are identical. The only diverging input is 
`build/gsp-classes/main`.
   
   Reproduced locally by changing only the source mtimes, with file content 
unchanged:
   
   | | mtimes | resulting class bytes |
   | --- | --- | --- |
   | before | 3 distinct | 3 distinct sets |
   | after a fixed `LAST_MODIFIED` | 3 distinct | byte-identical |
   
   A sibling closure class produced by the same task in the same run
   (`gsp_..._table_gsp$_run_closure1.class`), which carries no `LAST_MODIFIED` 
constant, is
   byte-identical in every run. That isolates the timestamp as the sole cause 
rather than general
   compiler nondeterminism.
   
   ## Measured cost
   
   Over 2026-07-29 → 2026-08-05 on `develocity.apache.org`, roughly 616 hours 
of avoidable CI task
   re-execution across this project trace to jars carrying precompiled GSPs, 
the largest single
   contributor being 
`:grails-test-examples-spring-security-ui-simple:assetCompile`. These are summed
   task re-executions rather than wall-clock, since much of the work runs in 
parallel.
   
   ## Note on the reload path
   
   `LAST_MODIFIED` is not unused. 
`GroovyPageMetaInfo.checkIfReloadableResourceHasChanged` reads the
   field directly and compares it against the live source timestamp to decide 
whether a precompiled
   page is stale, so any fix that fixes the value must also handle the "no 
timestamp recorded" case —
   otherwise every check reports a change. For GSPs in binary plugin jars the 
reload path is already
   unreachable (`DefaultGroovyPageLocator.resolveViewInBinaryPlugin` nulls the 
resource callable, and
   the jars ship no `.gsp` sources), but an application's own precompiled pages 
with reloading enabled
   would be affected.
   
   ## Environment
   
   - Branch: reproduced against `8.0.x`; the relevant sources are 
byte-identical on `7.0.x`
   - `GroovyPageCompiler.groovy:222`, `GroovyPageParser.java:905`, 
`GroovyPageMetaInfo.java:480`
   
   ## Attribution
   
   This was found while trialling Gradle's Build Caching Optimizer
   (https://develocity.ai/product/build-caching-optimizer/), an agent that 
locates avoidable
   build-cache misses from Develocity data. Generative tooling was used in 
preparing this report and
   the accompanying analysis; the findings were verified against the sources 
and build scans linked
   above.
   


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