Skip to content

Commit e99c008

Browse files
committed
Add default executionControl reconciliation for common Maven plugins
## 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
1 parent 5990c9f commit e99c008

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

src/main/java/org/apache/maven/buildcache/xml/CacheConfigImpl.java

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,18 +248,15 @@ public boolean isLogAllProperties(MojoExecution mojoExecution) {
248248
}
249249

250250
private GoalReconciliation findReconciliationConfig(MojoExecution mojoExecution) {
251-
if (cacheConfig.getExecutionControl() == null) {
252-
return null;
253-
}
251+
List<GoalReconciliation> reconciliation;
254252

255-
final ExecutionControl executionControl = cacheConfig.getExecutionControl();
256-
if (executionControl.getReconcile() == null) {
257-
return null;
253+
if (cacheConfig.getExecutionControl() == null || cacheConfig.getExecutionControl().getReconcile() == null) {
254+
// Use default reconciliation configs for common plugins
255+
reconciliation = getDefaultReconciliationConfigs();
256+
} else {
257+
reconciliation = cacheConfig.getExecutionControl().getReconcile().getPlugins();
258258
}
259259

260-
final List<GoalReconciliation> reconciliation =
261-
executionControl.getReconcile().getPlugins();
262-
263260
for (GoalReconciliation goalReconciliationConfig : reconciliation) {
264261
final String goal = mojoExecution.getGoal();
265262

@@ -271,6 +268,56 @@ private GoalReconciliation findReconciliationConfig(MojoExecution mojoExecution)
271268
return null;
272269
}
273270

271+
private List<GoalReconciliation> getDefaultReconciliationConfigs() {
272+
List<GoalReconciliation> defaults = new ArrayList<>();
273+
274+
// maven-compiler-plugin:compile - track source, target, release
275+
GoalReconciliation compilerCompile = new GoalReconciliation();
276+
compilerCompile.setArtifactId("maven-compiler-plugin");
277+
compilerCompile.setGoal("compile");
278+
279+
TrackedProperty source = new TrackedProperty();
280+
source.setPropertyName("source");
281+
compilerCompile.addReconcile(source);
282+
283+
TrackedProperty target = new TrackedProperty();
284+
target.setPropertyName("target");
285+
compilerCompile.addReconcile(target);
286+
287+
TrackedProperty release = new TrackedProperty();
288+
release.setPropertyName("release");
289+
compilerCompile.addReconcile(release);
290+
291+
defaults.add(compilerCompile);
292+
293+
// maven-compiler-plugin:testCompile - track source, target, release
294+
GoalReconciliation compilerTestCompile = new GoalReconciliation();
295+
compilerTestCompile.setArtifactId("maven-compiler-plugin");
296+
compilerTestCompile.setGoal("testCompile");
297+
298+
TrackedProperty testSource = new TrackedProperty();
299+
testSource.setPropertyName("source");
300+
compilerTestCompile.addReconcile(testSource);
301+
302+
TrackedProperty testTarget = new TrackedProperty();
303+
testTarget.setPropertyName("target");
304+
compilerTestCompile.addReconcile(testTarget);
305+
306+
TrackedProperty testRelease = new TrackedProperty();
307+
testRelease.setPropertyName("release");
308+
compilerTestCompile.addReconcile(testRelease);
309+
310+
defaults.add(compilerTestCompile);
311+
312+
// maven-install-plugin:install - always run (empty reconciliation means it's tracked)
313+
GoalReconciliation install = new GoalReconciliation();
314+
install.setArtifactId("maven-install-plugin");
315+
install.setGoal("install");
316+
defaults.add(install);
317+
318+
return defaults;
319+
}
320+
274321
@Nonnull
275322
@Override
276323
public List<PropertyName> getLoggedProperties(MojoExecution mojoExecution) {

src/site/markdown/how-to.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ Add `executionControl/runAlways` section:
160160
</executionControl>
161161
```
162162

163+
### Default Reconciliation Behavior
164+
165+
The build cache extension automatically tracks certain critical plugin properties by default, even without explicit
166+
`executionControl` configuration:
167+
168+
* **maven-compiler-plugin** (`compile` and `testCompile` goals): Tracks `source`, `target`, and `release` properties
169+
* **maven-install-plugin** (`install` goal): Tracked to ensure artifacts are installed when needed
170+
171+
This default behavior prevents common cache invalidation issues, particularly in multi-module JPMS (Java Platform Module System)
172+
projects where compiler version changes can cause compilation failures.
173+
163174
### I occasionally cached build with `-DskipTests=true`, and tests do not run now
164175

165176
If you add command line flags to your build, they do not participate in effective pom - Maven defers the final value

0 commit comments

Comments
 (0)