Skip to content

Commit 845717e

Browse files
committed
Convert annotation processors from dependencies to maven-compiler-plugin configuration
Closes gh-1781
1 parent 1922a09 commit 845717e

File tree

8 files changed

+684
-5
lines changed

8 files changed

+684
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2012 - present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.initializr.generator.spring.build.maven;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.stream.Collectors;
23+
24+
import io.spring.initializr.generator.buildsystem.Dependency;
25+
import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
26+
import io.spring.initializr.generator.buildsystem.maven.MavenPluginContainer;
27+
import io.spring.initializr.generator.spring.build.BuildCustomizer;
28+
import io.spring.initializr.generator.version.VersionProperty;
29+
import io.spring.initializr.generator.version.VersionReference;
30+
import org.jspecify.annotations.Nullable;
31+
32+
import org.springframework.core.Ordered;
33+
import org.springframework.util.Assert;
34+
35+
/**
36+
* A {@link BuildCustomizer} that converts annotation processor dependencies to
37+
* {@code maven-compiler-plugin} {@code annotationProcessorPaths} configuration.
38+
*
39+
* @author Moritz Halbritter
40+
*/
41+
class ConvertAnnotationProcessorsToPluginConfigBuildCustomizer implements BuildCustomizer<MavenBuild> {
42+
43+
@Override
44+
public void customize(MavenBuild build) {
45+
Set<String> ids = build.dependencies().ids().collect(Collectors.toSet());
46+
List<Dependency> annotationProcessors = new ArrayList<>();
47+
List<Dependency> testAnnotationProcessors = new ArrayList<>();
48+
for (String id : ids) {
49+
Dependency dependency = build.dependencies().get(id);
50+
Assert.state(dependency != null, "'dependency' must not be null");
51+
if (dependency.getScope() == null) {
52+
continue;
53+
}
54+
switch (dependency.getScope()) {
55+
case ANNOTATION_PROCESSOR -> {
56+
build.dependencies().remove(id);
57+
annotationProcessors.add(dependency);
58+
}
59+
case TEST_ANNOTATION_PROCESSOR -> {
60+
build.dependencies().remove(id);
61+
testAnnotationProcessors.add(dependency);
62+
}
63+
}
64+
}
65+
configureCompilerPlugin(build.plugins(), annotationProcessors, "default-compile", "compile", "compile");
66+
configureCompilerPlugin(build.plugins(), testAnnotationProcessors, "default-testCompile", "test-compile",
67+
"testCompile");
68+
}
69+
70+
private void configureCompilerPlugin(MavenPluginContainer plugins, List<Dependency> annotationProcessors,
71+
String executionId, String phase, String goal) {
72+
if (annotationProcessors.isEmpty()) {
73+
return;
74+
}
75+
plugins.add("org.apache.maven.plugins", "maven-compiler-plugin",
76+
(plugin) -> plugin.execution(executionId, (execution) -> {
77+
execution.phase(phase);
78+
execution.goal(goal);
79+
execution.configuration((config) -> {
80+
config.add("annotationProcessorPaths", (paths) -> {
81+
for (Dependency annotationProcessor : annotationProcessors) {
82+
paths.add("path", (path) -> {
83+
path.add("groupId", annotationProcessor.getGroupId());
84+
path.add("artifactId", annotationProcessor.getArtifactId());
85+
if (annotationProcessor.getClassifier() != null) {
86+
path.add("classifier", annotationProcessor.getClassifier());
87+
}
88+
String version = determineVersion(annotationProcessor.getVersion());
89+
if (version != null) {
90+
path.add("version", version);
91+
}
92+
if (annotationProcessor.getType() != null) {
93+
path.add("type", annotationProcessor.getType());
94+
}
95+
if (!annotationProcessor.getExclusions().isEmpty()) {
96+
path.add("exclusions", (exclusions) -> {
97+
for (Dependency.Exclusion exclusion : annotationProcessor.getExclusions()) {
98+
exclusions.add("exclusion", (exclusionElement) -> {
99+
exclusionElement.add("groupId", exclusion.getGroupId());
100+
exclusionElement.add("artifactId", exclusion.getArtifactId());
101+
});
102+
}
103+
});
104+
}
105+
});
106+
}
107+
});
108+
});
109+
}));
110+
}
111+
112+
private @Nullable String determineVersion(@Nullable VersionReference versionReference) {
113+
if (versionReference == null) {
114+
return null;
115+
}
116+
VersionProperty property = versionReference.getProperty();
117+
if (property != null) {
118+
return "${" + property.toStandardFormat() + "}";
119+
}
120+
return versionReference.getValue();
121+
}
122+
123+
@Override
124+
public int getOrder() {
125+
return Ordered.LOWEST_PRECEDENCE;
126+
}
127+
128+
}

initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/build/maven/MavenProjectGenerationConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* Maven as its build system.
4141
*
4242
* @author Andy Wilkinson
43+
* @author Moritz Halbritter
4344
*/
4445
@ProjectGenerationConfiguration
4546
@ConditionalOnBuildSystem(MavenBuildSystem.ID)
@@ -88,4 +89,9 @@ public BuildCustomizer<MavenBuild> mavenWarPackagingConfigurer() {
8889
return (build) -> build.settings().packaging("war");
8990
}
9091

92+
@Bean
93+
ConvertAnnotationProcessorsToPluginConfigBuildCustomizer convertAnnotationProcessorsToPluginConfigBuildCustomizer() {
94+
return new ConvertAnnotationProcessorsToPluginConfigBuildCustomizer();
95+
}
96+
9197
}

initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/build/BuildComplianceTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.stream.Stream;
2020

2121
import io.spring.initializr.generator.buildsystem.BuildSystem;
22+
import io.spring.initializr.generator.buildsystem.DependencyScope;
2223
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem;
2324
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
2425
import io.spring.initializr.generator.language.Language;
@@ -208,6 +209,26 @@ void annotationProcessorDependency(BuildSystem build, String fileName) {
208209
assertThat(project).textFile(fileName).as("Resource " + path).hasSameContentAs(new ClassPathResource(path));
209210
}
210211

212+
@ParameterizedTest
213+
@MethodSource("parameters")
214+
void testAnnotationProcessorDependency(BuildSystem build, String fileName) {
215+
Dependency dataJpa = Dependency.withId("data-jpa", "org.springframework.boot", "spring-boot-starter-data-jpa");
216+
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
217+
.addDependencyGroup("core", "web", "data-jpa")
218+
.build();
219+
ProjectStructure project = generateProject(java, build, "2.4.1", (description) -> {
220+
description.addDependency("configuration-processor",
221+
io.spring.initializr.generator.buildsystem.Dependency
222+
.withCoordinates("org.springframework.boot", "spring-boot-configuration-processor")
223+
.scope(DependencyScope.TEST_ANNOTATION_PROCESSOR)
224+
.build());
225+
description.addDependency("web", MetadataBuildItemMapper.toDependency(WEB));
226+
description.addDependency("data-jpa", MetadataBuildItemMapper.toDependency(dataJpa));
227+
}, metadata);
228+
String path = "project/" + build + "/test-annotation-processor-dependency-" + getAssertFileName(fileName);
229+
assertThat(project).textFile(fileName).as("Resource " + path).hasSameContentAs(new ClassPathResource(path));
230+
}
231+
211232
@ParameterizedTest
212233
@MethodSource("parameters")
213234
void bomWithOrdering(BuildSystem build, String fileName) {

0 commit comments

Comments
 (0)