Skip to content

[MCOMPILER-578] Track outputs across compiler executions - #1091

Open
wilx wants to merge 3 commits into
apache:maven-compiler-plugin-3.xfrom
wilx:issue-788-incremental-multi-execution
Open

[MCOMPILER-578] Track outputs across compiler executions#1091
wilx wants to merge 3 commits into
apache:maven-compiler-plugin-3.xfrom
wilx:issue-788-incremental-multi-execution

Conversation

@wilx

@wilx wilx commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Keep the final class files deterministic when multiple compiler executions use different release levels and share an
output directory.

Root cause

An earlier execution can overwrite an existing class file without changing its filename. IncrementalBuildHelper
compares input and output file names, so a later execution can incorrectly consider its source up to date even though
a different execution produced the shared output.

Changes

  • Add an Invoker regression test that runs clean compile followed by compile and verifies the Java 8 classes and
    Java 11 module descriptor.
  • Track the last goal@executionId that processed each mapped output in Maven's per-project plugin context.
  • Recompile when another execution processed an overlapping output, while allowing a repeated invocation of the same
    execution to remain up to date.
  • Avoid filesystem timestamps and their platform-dependent precision.

Validation

  • mvn -Prun-its verify: 77 passed, 0 failed, 5 environment-specific skips.
  • Focused MCOMPILER-525 and MCOMPILER-578 Invoker tests: passed.
  • Unit tests: 32 passed.
  • Spotless, Checkstyle, and git diff --check: passed.

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Make sure there is a JIRA issue filed
    for the change (usually before you start working on it). Trivial changes like typos do not
    require a JIRA issue. Your pull request should address just this issue, without
    pulling in other changes.
  • Each commit in the pull request should have a meaningful subject line and body.
  • Format the pull request title like [MCOMPILER-XXX] - Fixes bug in ApproximateQuantiles,
    where you replace MCOMPILER-XXX with the appropriate JIRA issue. Best practice
    is to use the JIRA issue title in the pull request title and in the first line of the
    commit message.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean verify to make sure basic checks pass. A more thorough check will
    be performed on your pull request automatically.
  • You have run the integration tests successfully (mvn -Prun-its clean verify).

If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.

To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

Fixes #788

wilx added 2 commits July 28, 2026 18:41
Run clean compile followed by compile and verify that Java 8 classes and the Java 11 module descriptor retain their configured class-file versions. The test exposes the incremental compilation failure before the production fix.
Record the last compiler execution that processed each mapped output in the shared plugin context. Recompile when a different execution overlaps that output while allowing repeated invocations of the same execution to remain up to date.

Fixes apache#788
@wilx
wilx marked this pull request as ready for review July 28, 2026 17:47
@elharo elharo changed the title [MCOMPILER-578] - Track outputs across compiler executions [MCOMPILER-578] Track outputs across compiler executions Jul 28, 2026
@elharo
elharo requested a review from Copilot July 28, 2026 20:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR fixes incremental-compilation correctness when multiple compiler executions share an output directory but use different release levels, by tracking which execution last produced each output within the Maven session.

Changes:

  • Introduces a per-project, per-session output registry keyed by goal@executionId to detect overlapping outputs between executions.
  • Updates AbstractCompilerMojo incremental rebuild-cause detection to force recompilation when another execution last produced an expected output.
  • Adds a new Invoker IT (MCOMPILER-578) and unit tests for the output registry behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java Computes expected outputs and triggers rebuilds when outputs overlap across executions; records processed outputs in plugin context.
src/main/java/org/apache/maven/plugin/compiler/CompilationOutputRegistry.java New registry to map expected output paths to the last goal@executionId that processed them.
src/test/java/org/apache/maven/plugin/compiler/CompilationOutputRegistryTest.java New unit tests validating registry semantics across executions and disjoint outputs.
src/it/MCOMPILER-578/pom.xml New integration test project with multiple compile executions using different --release values into the same output dir.
src/it/MCOMPILER-578/verify.groovy Validates resulting classfile major versions for Java 8 class and Java 11 module-info.class.
src/it/MCOMPILER-578/invoker.properties Runs clean compile then compile to exercise incremental behavior.
src/it/MCOMPILER-578/src/main/java/org/example/Example.java Minimal class compiled by different executions.
src/it/MCOMPILER-578/src/main/java/org/example/package-info.java Ensures package presence without generating missing package-info class.
src/it/MCOMPILER-578/src/main/java/module-info.java Module descriptor compiled with Java 11 settings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1619 to +1625
private boolean hasPreviouslyCompiledOutput(String compilerExecution, Set<Path> outputs) {
Optional<Path> output = CompilationOutputRegistry.find(getPluginContext(), compilerExecution, outputs);
if (output.isPresent() && (getLog().isDebugEnabled() || showCompilationChanges)) {
getLog().info("\tOutput from another compiler execution: " + output.get());
}
return output.isPresent();
}
Comment on lines +67 to +78
for (String sourceRoot : sourceRoots) {
Path root = Paths.get(sourceRoot).toAbsolutePath().normalize();
for (File source : sources) {
Path path = source.toPath().toAbsolutePath().normalize();
if (path.startsWith(root)) {
for (File output : mapping.getTargetFiles(
outputDirectory, root.relativize(path).toString())) {
outputs.add(output.toPath().toAbsolutePath().normalize());
}
}
}
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really something people do? SMH

Comment thread src/it/MCOMPILER-578/verify.groovy Outdated
Comment on lines +22 to +24
def exampleMajorVersion = exampleClass.bytes[7] & 0xFF
// major_version: 52 = Java 8, from the base-compile execution.
assert exampleMajorVersion == 52
Comment thread src/it/MCOMPILER-578/verify.groovy Outdated
Comment on lines +28 to +30
def moduleInfoMajorVersion = moduleInfoClass.bytes[7] & 0xFF
// major_version: 55 = Java 11, from the base-modules-compile execution.
assert moduleInfoMajorVersion == 55
Comment on lines +38 to +40
private static final Path OUTPUT = Paths.get("target/classes/Example.class");

private static final Path OTHER_OUTPUT = Paths.get("target/classes/Other.class");
@wilx

wilx commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

I have pushed a fix for all of the review comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants