Skip to content

Commit 3442afd

Browse files
committed
GH-1133 - More resilient APT output location detection.
Gradle's APT handling seems to significantly differ from Maven's as the Java compilation runs from a completely different base folder than the actual project compiled. Even more so, for multi-module projects, the base folder is always the same, which causes APT output using Java's plain File API to override itself in a multi-module project. I've tweaked the output folder detection to look up well-known APT parameters provided by either the Spring Boot plugin (org.springframework.boot.configurationprocessor.additionalMetadataLocations) or KAPT (for Kotlin-based projects, kapt.kotlin.generated) and derive the actual output folder from the values set for those. If neither of these is set, we fall back to the original local folder.
1 parent 47fa1fb commit 3442afd

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

spring-modulith-apt/src/main/java/org/springframework/modulith/apt/SpringModulithProcessor.java

+25-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.FileWriter;
2525
import java.io.IOException;
2626
import java.nio.file.Files;
27+
import java.nio.file.Path;
2728
import java.util.Collection;
2829
import java.util.Collections;
2930
import java.util.Comparator;
@@ -70,6 +71,7 @@ public class SpringModulithProcessor implements Processor {
7071

7172
private Elements elements;
7273
private Messager messager;
74+
private File javadocJson;
7375
private boolean testExecution;
7476
private Set<TypeMetadata> metadata = new HashSet<>();
7577

@@ -123,6 +125,7 @@ public void init(ProcessingEnvironment environment) {
123125

124126
this.elements = environment.getElementUtils();
125127
this.messager = environment.getMessager();
128+
this.javadocJson = getAptOutputFolder(environment).resolve(JSON_LOCATION).toFile();
126129

127130
try {
128131

@@ -165,8 +168,6 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
165168

166169
if (roundEnv.processingOver()) {
167170

168-
messager.printMessage(Kind.NOTE, "Extracting Javadoc into " + JSON_LOCATION + ".");
169-
170171
var methodJson = JsonWriter.<MethodMetadata> of(inner -> {
171172
inner.add("name", MethodMetadata::name);
172173
inner.add("signature", MethodMetadata::signature);
@@ -185,11 +186,11 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
185186
});
186187
});
187188

188-
File file = new File(JSON_LOCATION);
189+
messager.printMessage(Kind.NOTE, "Extracting Javadoc into " + javadocJson.getAbsolutePath() + ".");
189190

190-
if (!file.exists()) {
191+
if (!javadocJson.exists()) {
191192
try {
192-
Files.createDirectories(file.toPath().getParent());
193+
Files.createDirectories(javadocJson.toPath().getParent());
193194
} catch (IOException e) {
194195
throw new RuntimeException(e);
195196
}
@@ -202,7 +203,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
202203
.map(typeJson::write)
203204
.toList());
204205

205-
try (var writer = new FileWriter(file)) {
206+
try (var writer = new FileWriter(javadocJson)) {
206207
writer.write(output);
207208
} catch (IOException e) {
208209
throw new RuntimeException(e);
@@ -305,4 +306,22 @@ private static Stream<TypeElementWrapper> getTypes(TypeElementWrapper type) {
305306

306307
return Stream.concat(Stream.of(type), enclosed);
307308
}
309+
310+
private static Path getAptOutputFolder(ProcessingEnvironment environment) {
311+
312+
var boot = environment.getOptions()
313+
.get("org.springframework.boot.configurationprocessor.additionalMetadataLocations");
314+
315+
if (boot != null) {
316+
return Path.of(boot.substring(0, boot.indexOf("/src/main/resources")));
317+
}
318+
319+
var kapt = environment.getOptions().get("kapt.kotlin.generated");
320+
321+
if (kapt != null) {
322+
return Path.of(kapt.substring(0, kapt.indexOf("/build/generated/source")));
323+
}
324+
325+
return Path.of(".");
326+
}
308327
}

0 commit comments

Comments
 (0)