@@ -6,6 +6,7 @@ import org.gradle.api.Plugin
66import org.gradle.api.Project
77import org.gradle.api.file.FileCollection
88import org.gradle.api.tasks.SourceSetContainer
9+ import org.gradle.api.tasks.compile.JavaCompile
910import org.gradle.api.tasks.testing.Test
1011import org.gradle.language.base.plugins.LifecycleBasePlugin
1112
@@ -30,6 +31,10 @@ abstract class SpringBootMatrixExtension @Inject constructor(private val project
3031 * `gradle/spring-boot-versions.json`, and `allIntegrationTestsBoot<line>` for all of them. The CI
3132 * workflows read the same file and run each version in its own job. A WAR module uses its Boot
3233 * module's line, because the Boot BOM decides its Spring version.
34+ *
35+ * The line's first version must be the oldest. The module's main code compiles against it in
36+ * `compileJavaBoot<version>`, part of that version's aggregate, because the main compilation only
37+ * proves the code compiles against the catalog's version.
3338 */
3439 fun versions (line : Int ) {
3540 val file = project.layout.settingsDirectory.file(" gradle/spring-boot-versions.json" )
@@ -48,6 +53,22 @@ abstract class SpringBootMatrixExtension @Inject constructor(private val project
4853 group = LifecycleBasePlugin .VERIFICATION_GROUP
4954 }
5055 }
56+
57+ val oldest = versions.first()
58+ val compileClasspath = classpath(" main" , oldest, compile = true )
59+ val compileOldest =
60+ project.tasks.register(" compileJava${suffix(oldest)} " , JavaCompile ::class .java) {
61+ description = " Compiles the main Java sources against Spring Boot $oldest ."
62+ group = LifecycleBasePlugin .VERIFICATION_GROUP
63+ val compileJava = project.tasks.named(" compileJava" , JavaCompile ::class .java).get()
64+ source = sourceSet(" main" ).java
65+ classpath = compileClasspath
66+ destinationDirectory.set(project.layout.buildDirectory.dir(" classes/java/main${suffix(oldest)} " ))
67+ javaCompiler.set(compileJava.javaCompiler)
68+ options.release.set(compileJava.options.release)
69+ options.annotationProcessorPath = compileJava.options.annotationProcessorPath
70+ }
71+ project.tasks.named(aggregateName(oldest)) { dependsOn(compileOldest) }
5172 }
5273
5374 /* *
@@ -74,28 +95,29 @@ abstract class SpringBootMatrixExtension @Inject constructor(private val project
7495 }
7596
7697 /* * [sourceSet]'s output and runtime dependencies, with Spring Boot at [version]. */
77- fun runtimeClasspath (sourceSet : String , version : String ): FileCollection {
98+ fun runtimeClasspath (sourceSet : String , version : String ): FileCollection =
99+ sourceSet(sourceSet).output + classpath(sourceSet, version, compile = false )
100+
101+ /* * [sourceSet]'s compile or runtime classpath dependencies, with Spring Boot at [version]. */
102+ private fun classpath (sourceSet : String , version : String , compile : Boolean ): FileCollection {
78103 val sources = sourceSet(sourceSet)
79- val name = " $sourceSet${suffix(version)} RuntimeClasspath"
104+ val base =
105+ if (compile) sources.compileClasspathConfigurationName
106+ else sources.runtimeClasspathConfigurationName
107+ val name = " $sourceSet${suffix(version)}${if (compile) " Compile" else " Runtime" } Classpath"
80108 val configurations = project.configurations
81- val dependencies =
82- configurations.findByName(name)
83- ? : configurations.create(name) {
84- isCanBeConsumed = false
85- extendsFrom(
86- configurations.getByName(sources.implementationConfigurationName),
87- configurations.getByName(sources.runtimeOnlyConfigurationName),
88- )
89- attributes.addAllLater(
90- configurations.getByName(sources.runtimeClasspathConfigurationName).attributes
91- )
92- // What setting the version in the catalog does: every Spring Boot artifact, the BOM
93- // included, is in this group. Libraries pinned to their own version still win conflicts.
94- resolutionStrategy.eachDependency {
95- if (requested.group == " org.springframework.boot" ) useVersion(version)
96- }
109+ return configurations.findByName(name)
110+ ? : configurations.create(name) {
111+ isCanBeConsumed = false
112+ val baseConfiguration = configurations.getByName(base)
113+ extendsFrom(* baseConfiguration.extendsFrom.toTypedArray())
114+ attributes.addAllLater(baseConfiguration.attributes)
115+ // What setting the version in the catalog does: every Spring Boot artifact, the BOM
116+ // included, is in this group. Libraries pinned to their own version still win conflicts.
117+ resolutionStrategy.eachDependency {
118+ if (requested.group == " org.springframework.boot" ) useVersion(version)
97119 }
98- return sources.output + dependencies
120+ }
99121 }
100122
101123 private fun sourceSet (name : String ) =
0 commit comments