Skip to content

Commit a0c005f

Browse files
committed
Add maven.build.cache.cacheCompile property to control compile-phase caching
Added new configuration property maven.build.cache.cacheCompile (default: true) to address reviewer concerns about performance overhead during active development. Changes: - CacheConfig: Added isCacheCompile() method with javadoc - CacheConfigImpl: Added CACHE_COMPILE constant and implementation (default true) - CacheControllerImpl: Wrapped attachGeneratedSources() and attachOutputs() calls in isCacheCompile() check - CacheCompileDisabledTest: Integration tests verifying behavior when disabled Benefits: - Maintains fix for issue #393 (default behavior unchanged) - Allows developers to opt-out of compile caching with: -Dmaven.build.cache.cacheCompile=false - Reduces IO overhead (no zipping/uploading) during active development - Users working on large multi-module projects can keep it enabled Usage: # Disable compile caching to reduce overhead during development: mvn clean compile -Dmaven.build.cache.cacheCompile=false # Enable for CI/multi-module scenarios (default): mvn clean compile
1 parent 92822da commit a0c005f

File tree

4 files changed

+153
-2
lines changed

4 files changed

+153
-2
lines changed

src/main/java/org/apache/maven/buildcache/CacheControllerImpl.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,13 @@ public void save(
525525
final org.apache.maven.artifact.Artifact projectArtifact = project.getArtifact();
526526
final boolean hasPackagePhase = project.hasLifecyclePhase("package");
527527

528-
attachGeneratedSources(project, state, buildStartTime);
529-
attachOutputs(project, state, buildStartTime);
528+
// Cache compile outputs (classes, test-classes, generated sources) if enabled
529+
// This allows compile-only builds to create restorable cache entries
530+
// Can be disabled with -Dmaven.build.cache.cacheCompile=false to reduce IO overhead
531+
if (cacheConfig.isCacheCompile()) {
532+
attachGeneratedSources(project, state, buildStartTime);
533+
attachOutputs(project, state, buildStartTime);
534+
}
530535

531536
final List<org.apache.maven.artifact.Artifact> attachedArtifacts = project.getAttachedArtifacts() != null
532537
? project.getAttachedArtifacts()

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,15 @@ public interface CacheConfig {
152152
* Flag to save in cache only if a build went through the clean lifecycle
153153
*/
154154
boolean isMandatoryClean();
155+
156+
/**
157+
* Flag to cache compile phase outputs (classes, test-classes, generated sources).
158+
* When enabled (default), compile-only builds create cache entries that can be restored
159+
* by subsequent builds. When disabled, caching only occurs during package phase or later.
160+
* <p>
161+
* Use: -Dmaven.build.cache.cacheCompile=(true|false)
162+
* <p>
163+
* Default: true
164+
*/
165+
boolean isCacheCompile();
155166
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public class CacheConfigImpl implements org.apache.maven.buildcache.xml.CacheCon
9797
public static final String RESTORE_GENERATED_SOURCES_PROPERTY_NAME = "maven.build.cache.restoreGeneratedSources";
9898
public static final String ALWAYS_RUN_PLUGINS = "maven.build.cache.alwaysRunPlugins";
9999
public static final String MANDATORY_CLEAN = "maven.build.cache.mandatoryClean";
100+
public static final String CACHE_COMPILE = "maven.build.cache.cacheCompile";
100101

101102
/**
102103
* Flag to control if we should skip lookup for cached artifacts globally or for a particular project even if
@@ -541,6 +542,11 @@ public boolean isMandatoryClean() {
541542
return getProperty(MANDATORY_CLEAN, getConfiguration().isMandatoryClean());
542543
}
543544

545+
@Override
546+
public boolean isCacheCompile() {
547+
return getProperty(CACHE_COMPILE, true);
548+
}
549+
544550
@Override
545551
public String getId() {
546552
checkInitializedState();
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.buildcache.its;
20+
21+
import java.io.IOException;
22+
import java.nio.file.Files;
23+
import java.nio.file.Path;
24+
import java.nio.file.Paths;
25+
import java.util.Arrays;
26+
import java.util.stream.Stream;
27+
28+
import org.apache.maven.buildcache.its.junit.IntegrationTest;
29+
import org.apache.maven.it.VerificationException;
30+
import org.apache.maven.it.Verifier;
31+
import org.junit.jupiter.api.Test;
32+
33+
import static org.junit.jupiter.api.Assertions.assertFalse;
34+
import static org.junit.jupiter.api.Assertions.assertTrue;
35+
36+
/**
37+
* Tests that the maven.build.cache.cacheCompile property correctly disables
38+
* caching of compile-phase outputs.
39+
*/
40+
@IntegrationTest("src/test/projects/simple-project")
41+
class CacheCompileDisabledTest {
42+
43+
@Test
44+
void compileDoesNotCacheWhenDisabled(Verifier verifier) throws VerificationException, IOException {
45+
verifier.setAutoclean(false);
46+
47+
Path basedir = Paths.get(verifier.getBasedir());
48+
Path localCache = basedir.resolveSibling("cache-local");
49+
50+
// Clean cache before test
51+
if (Files.exists(localCache)) {
52+
deleteDirectory(localCache);
53+
}
54+
Files.createDirectories(localCache);
55+
56+
// First compile with cacheCompile disabled
57+
verifier.setLogFileName("../log-compile-disabled.txt");
58+
verifier.addCliOption("-Dmaven.build.cache.cacheCompile=false");
59+
verifier.executeGoals(Arrays.asList("clean", "compile"));
60+
verifier.verifyErrorFreeLog();
61+
62+
// Verify NO cache entry was created (no buildinfo.xml in local cache)
63+
boolean hasCacheEntry = Files.walk(localCache)
64+
.anyMatch(p -> p.getFileName().toString().equals("buildinfo.xml"));
65+
assertFalse(hasCacheEntry,
66+
"Cache entry should NOT be created when maven.build.cache.cacheCompile=false");
67+
68+
// Clean project and run compile again
69+
verifier.setLogFileName("../log-compile-disabled-2.txt");
70+
verifier.addCliOption("-Dmaven.build.cache.cacheCompile=false");
71+
verifier.executeGoals(Arrays.asList("clean", "compile"));
72+
verifier.verifyErrorFreeLog();
73+
74+
// Verify cache miss (should NOT restore from cache)
75+
Path logFile = basedir.getParent().resolve("log-compile-disabled-2.txt");
76+
String logContent = new String(Files.readAllBytes(logFile));
77+
assertFalse(logContent.contains("Found cached build, restoring"),
78+
"Should NOT restore from cache when cacheCompile was disabled");
79+
}
80+
81+
@Test
82+
void compileCreatesCacheEntryWhenEnabled(Verifier verifier) throws VerificationException, IOException {
83+
verifier.setAutoclean(false);
84+
85+
Path basedir = Paths.get(verifier.getBasedir());
86+
Path localCache = basedir.resolveSibling("cache-local");
87+
88+
// Clean cache before test
89+
if (Files.exists(localCache)) {
90+
deleteDirectory(localCache);
91+
}
92+
Files.createDirectories(localCache);
93+
94+
// First compile with cacheCompile enabled (default)
95+
verifier.setLogFileName("../log-compile-enabled.txt");
96+
verifier.executeGoals(Arrays.asList("clean", "compile"));
97+
verifier.verifyErrorFreeLog();
98+
99+
// Verify cache entry WAS created
100+
boolean hasCacheEntry = Files.walk(localCache)
101+
.anyMatch(p -> p.getFileName().toString().equals("buildinfo.xml"));
102+
assertTrue(hasCacheEntry,
103+
"Cache entry should be created when maven.build.cache.cacheCompile=true (default)");
104+
105+
// Clean project and run compile again
106+
verifier.setLogFileName("../log-compile-enabled-2.txt");
107+
verifier.executeGoals(Arrays.asList("clean", "compile"));
108+
verifier.verifyErrorFreeLog();
109+
110+
// Verify cache hit (should restore from cache)
111+
verifier.verifyTextInLog("Found cached build, restoring");
112+
verifier.verifyTextInLog("Skipping plugin execution (cached): compiler:compile");
113+
}
114+
115+
private void deleteDirectory(Path directory) throws IOException {
116+
if (Files.exists(directory)) {
117+
try (Stream<Path> walk = Files.walk(directory)) {
118+
walk.sorted((a, b) -> b.compareTo(a))
119+
.forEach(path -> {
120+
try {
121+
Files.delete(path);
122+
} catch (IOException e) {
123+
// Ignore
124+
}
125+
});
126+
}
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)