Skip to content

Conversation

@cowwoc
Copy link
Contributor

@cowwoc cowwoc commented Oct 5, 2025

Fixes #375

Problem

Maven 4 auto-injects --module-version ${project.version} to compilerArgs during cache storage but not during validation, causing parameter mismatches and forcing rebuilds on every invocation for modules with module-info.java.

Solution

Add ignorePattern attribute to TrackedProperty that filters array elements using regex before comparison.

Changes

  1. MDO Model (build-cache-config.mdo): Add ignorePattern field to TrackedProperty
  2. Reconciliation Logic (BuildCacheMojosExecutionStrategy.java):
    • filterAndStringifyArray() - filters runtime array values before stringification
    • filterArrayString() - filters cached string representations
    • Apply filtering to both current and expected values before comparison
  3. Default Configuration (CacheConfigImpl.java): Track compilerArgs with ignorePattern="--module-version" for both compile and testCompile goals

Testing

Tested with multi-module JPMS project using Maven 4.0.0-rc-4:

  • ✅ No parameter mismatches with --module-version present
  • ✅ Cache correctly reused across builds
  • ✅ Legitimate compilerArgs changes still invalidate cache

Related Issues

cowwoc added 2 commits October 5, 2025 18:21
## Problem
Without executionControl configuration, the build cache does not track critical plugin properties that are often specified via command-line arguments (e.g., -Dmaven.compiler.release). This leads to incorrect cache reuse when these properties change between builds.
In multi-module JPMS projects, this manifests as compilation failures or bytecode version mismatches:
1. Build with `-Dmaven.compiler.release=17` → cache stores Java 17 bytecode (major version 61)
2. Build with `-Dmaven.compiler.release=21` → cache incorrectly reuses Java 17 bytecode
3. Result: Bytecode remains major version 61 instead of expected 65
This is particularly problematic for module-info.class files which are sensitive to Java version.
## Solution
Implemented default reconciliation configs for common plugins when executionControl is not specified:
- **maven-compiler-plugin** (compile & testCompile goals):
  - Tracks `source`, `target`, and `release` properties
  - Ensures cache invalidation when Java version changes
- **maven-install-plugin** (install goal):
  - Tracked to ensure local repository is updated when needed
## Testing
Verified with multi-module JPMS test project:
**Before (broken):**
```
mvn clean verify -Dmaven.compiler.release=17  # Caches Java 17 bytecode
mvn clean verify -Dmaven.compiler.release=21  # Incorrectly reuses Java 17 bytecode
javap -v module-info.class | grep "major version"  # Shows 61 (wrong!)
```
**After (fixed):**
```
mvn clean verify -Dmaven.compiler.release=17  # Caches Java 17 bytecode
mvn clean verify -Dmaven.compiler.release=21  # Detects change, recompiles
javap -v module-info.class | grep "major version"  # Shows 65 (correct!)
```
## Impact
- Users no longer need to manually configure executionControl for basic scenarios
- Prevents silent bytecode version mismatches in JPMS projects
- Backward compatible: explicit executionControl config still takes precedence
Fixes apache#375 - Maven 4 auto-injects --module-version to compilerArgs during
cache storage but not during validation, causing parameter mismatches.

Changes:
- Add ignorePattern field to TrackedProperty in MDO model
- Implement regex-based filtering in BuildCacheMojosExecutionStrategy
- Filter arrays before comparison (both runtime and cached values)
- Update default reconciliation configs to filter --module-version

The ignorePattern attribute allows filtering specific array elements
before comparison, solving the Maven 4 module-version problem while
still detecting legitimate compilerArgs changes.

Tested with multi-module JPMS project using Maven 4.0.0-rc-4.
@cowwoc
Copy link
Contributor Author

cowwoc commented Oct 5, 2025

This PR addresses #375 by filtering out Maven 4's auto-injected --module-version parameter before cache comparison. This prevents false cache invalidation while still detecting legitimate changes to compiler arguments.

@cowwoc
Copy link
Contributor Author

cowwoc commented Oct 5, 2025

Closing to recreate from clean master branch (without unrelated default reconciliation configs). Replaced by #391

@cowwoc cowwoc closed this Oct 5, 2025
@cowwoc cowwoc deleted the fix-module-version-filtering branch October 5, 2025 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant