cowwoc opened a new pull request, #395:
URL: https://github.com/apache/maven-build-cache-extension/pull/395

   ## Problem
   
   Maven 4 automatically injects `--module-version ${project.version}` into 
compiler arguments **during execution**, but the build cache validates 
properties **before execution**. This creates a timing mismatch that causes 
cache invalidation:
   
   - **First build**: No cache exists → properties captured during/after 
execution (WITH Maven 4 injection)
   - **Second build**: Cache exists → properties captured during validation 
(WITHOUT injection yet) → mismatch → cache invalidated
   
   ## Root Cause Analysis
   
   The cache extension currently reads plugin properties at **different 
lifecycle points** for different builds:
   
   ```
   First Build Timeline:
     1. findCachedBuild() → no cache found
     2. Mojos execute → Maven 4 injects --module-version
     3. beforeMojoExecution() fires → captures properties WITH injection
     4. save() stores properties from execution events
   
   Second Build Timeline:
     1. findCachedBuild() → cache found
     2. verifyCacheConsistency() → creates mojo via getConfiguredMojo()
     3. Reads properties → WITHOUT injection (too early in lifecycle)
     4. Compares to first build's stored values (WITH injection)
     5. MISMATCH → cache invalidated!
   ```
   
   The problem: **validation reads BEFORE injection, storage reads AFTER 
injection**.
   
   ## Solution
   
   Capture properties at **validation time** for ALL builds (even when no cache 
exists). This ensures both validation and storage read at the same lifecycle 
point.
   
   ### Implementation
   
   1. **Modified `CacheResult`** to store validation-time mojo events
   2. **Modified `BuildCacheMojosExecutionStrategy`** to capture properties 
immediately after `findCachedBuild()`
   3. **Modified `save()`** to use validation-time events instead of 
execution-time events
   
   ### Key Code Changes
   
   ```java
   // In BuildCacheMojosExecutionStrategy.execute():
   result = cacheController.findCachedBuild(session, project, mojoExecutions, 
skipCache);
   
   // NEW: Capture validation-time properties for ALL mojos
   Map<String, MojoExecutionEvent> validationTimeEvents =
       captureValidationTimeProperties(session, project, mojoExecutions);
   
   // Store in result
   result = CacheResult.rebuilded(result, validationTimeEvents);
   ```
   
   ```java
   // In save():
   // Use validation-time events instead of execution-time events
   Map<String, MojoExecutionEvent> propertyEvents =
       cacheResult.getValidationTimeEvents() != null
           ? cacheResult.getValidationTimeEvents()  // Use validation-time
           : executionEvents;                        // Fallback to 
execution-time
   
   List<CompletedExecution> completedExecution =
       buildExecutionInfo(mojoExecutions, propertyEvents);
   ```
   
   ### New Timeline (Both Builds)
   
   ```
   First Build:
     1. findCachedBuild() → no cache
     2. captureValidationTimeProperties() → reads WITHOUT injection
     3. Mojos execute → Maven 4 injects (but we don't use these values)
     4. save() uses validation-time properties → stores WITHOUT injection
   
   Second Build:
     1. findCachedBuild() → cache found
     2. verifyCacheConsistency() → reads WITHOUT injection
     3. captureValidationTimeProperties() → reads WITHOUT injection
     4. Compares to first build → BOTH without injection → MATCH!
   ```
   
   ## Benefits Over PR #391
   
   | Aspect | PR #391 (`ignorePattern`) | This PR (Validation-Time Capture) |
   |--------|--------------------------|-----------------------------------|
   | **Approach** | Workaround: Filter mismatched values | Fix: Eliminate 
timing mismatch |
   | **Configuration** | Required | None needed |
   | **Flexibility** | Pattern must match version format | Format-agnostic |
   | **Maintenance** | Patterns need updates | No maintenance |
   | **Scope** | Only fixes known patterns | Fixes ALL auto-injected properties 
|
   
   ## Testing
   
   Created comprehensive integration tests:
   
   1. **Maven4JpmsModuleTest** - JPMS module with Maven 4 auto-injection of 
`--module-version`
   2. **ExplicitModuleVersionTest** - JPMS module with explicit `moduleVersion` 
configuration
   3. **NonJpmsProjectTest** - Regular Java project without JPMS (ensures no 
regression)
   4. **MultiModuleJpmsTest** - Multi-module project with mixed JPMS and 
non-JPMS modules
   
   All tests verify:
   - ✅ First build creates cache
   - ✅ Second build restores from cache (NO cache invalidation)
   - ✅ NO `ignorePattern` configuration required
   
   ## Backward Compatibility
   
   - Fully backward compatible
   - Existing caches remain valid
   - No configuration changes required
   - `ignorePattern` still works but is no longer necessary for Maven 4 
injection
   
   ## Alternative Approaches Considered
   
   1. **Store validation-time values only** ❌ - Would lose auditability of what 
actually executed
   2. **Delay validation until execution** ❌ - Would lose early cache-miss 
detection performance
   3. **Pattern-based filtering (PR #391)** ❌ - Treats symptom, not root cause
   4. **Maven core changes** ❌ - Outside our control
   5. **Validation-time capture (this PR)** ✅ - Fixes root cause, no 
configuration needed
   
   ## Related Issues
   
   - Fixes #375
   - Alternative to #391
   - Related to Maven 4 JPMS module compilation
   
   ## Migration
   
   No migration needed. This change is transparent to users. Existing projects 
will benefit automatically.


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