|
36 | 36 | import org.gradle.api.plugins.JavaPlugin; |
37 | 37 | import org.gradle.api.plugins.JavaPluginExtension; |
38 | 38 | import org.gradle.api.provider.Provider; |
39 | | -import org.gradle.api.provider.ProviderFactory; |
40 | 39 | import org.gradle.api.tasks.SourceSet; |
41 | 40 | import org.gradle.api.tasks.SourceSetContainer; |
42 | 41 | import org.gradle.api.tasks.TaskProvider; |
43 | 42 | import org.gradle.api.tasks.bundling.Jar; |
44 | 43 | import org.gradle.api.tasks.compile.JavaCompile; |
45 | 44 | import org.gradle.jvm.toolchain.JavaToolchainService; |
46 | 45 | import org.gradle.jvm.toolchain.JavaToolchainSpec; |
| 46 | +import org.gradle.util.GradleVersion; |
| 47 | +import org.jspecify.annotations.NonNull; |
47 | 48 | import org.jspecify.annotations.Nullable; |
48 | 49 |
|
49 | 50 | import org.springframework.boot.gradle.dsl.SpringBootExtension; |
@@ -281,48 +282,67 @@ private void configureAdditionalMetadataLocations(JavaCompile compile) { |
281 | 282 | .ifPresent((locations) -> compile.doFirst(new AdditionalMetadataLocationsConfigurer(locations))); |
282 | 283 | } |
283 | 284 |
|
284 | | - @SuppressWarnings({ "rawtypes", "unchecked" }) |
| 285 | + /** |
| 286 | + * In Gradle < 9.1.0, we don't have access to {@link AttributeContainer#addAllLater}, |
| 287 | + * so we will just copy the attributes individually. |
| 288 | + * @param from configuration from which to copy attributes |
| 289 | + * @param to configuration to which attributes will be copied |
| 290 | + */ |
| 291 | + @SuppressWarnings({ "rawtypes", "unchecked", "NullAway" }) |
| 292 | + private static void copyAttributes( |
| 293 | + @NonNull Provider<Configuration> from, |
| 294 | + @NonNull Configuration to) { |
| 295 | + if (GradleVersion.current().compareTo(GradleVersion.version("9.1.0")) < 0) { |
| 296 | + to.attributes((attributes) -> { |
| 297 | + AttributeContainer sourceAttributes = from.get().getAttributes(); |
| 298 | + for (Attribute attribute : sourceAttributes.keySet()) { |
| 299 | + attributes.attributeProvider(attribute, |
| 300 | + from.map((source) -> source.getAttributes().getAttribute(attribute))); |
| 301 | + } |
| 302 | + }); |
| 303 | + } |
| 304 | + else { |
| 305 | + to.getAttributes().addAllLater(from.map(Configuration::getAttributes).get()); |
| 306 | + } |
| 307 | + } |
| 308 | + |
285 | 309 | private void configureProductionRuntimeClasspathConfiguration(Project project) { |
286 | | - Configuration productionRuntimeClasspath = project.getConfigurations() |
287 | | - .create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
288 | | - Configuration runtimeClasspath = project.getConfigurations() |
289 | | - .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
290 | | - productionRuntimeClasspath.attributes((attributes) -> { |
291 | | - ProviderFactory providers = project.getProviders(); |
292 | | - AttributeContainer sourceAttributes = runtimeClasspath.getAttributes(); |
293 | | - for (Attribute attribute : sourceAttributes.keySet()) { |
294 | | - attributes.attributeProvider(attribute, |
295 | | - providers.provider(() -> sourceAttributes.getAttribute(attribute))); |
296 | | - } |
| 310 | + Provider<Configuration> runtimeClasspath = project.getConfigurations() |
| 311 | + .named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
| 312 | + project.getConfigurations().create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME, (prc) -> { |
| 313 | + copyAttributes(runtimeClasspath, prc); |
| 314 | + prc.setExtendsFrom(runtimeClasspath.get().getExtendsFrom()); |
| 315 | + prc.setCanBeResolved(runtimeClasspath.get().isCanBeResolved()); |
| 316 | + prc.setCanBeConsumed(runtimeClasspath.get().isCanBeConsumed()); |
| 317 | + prc.shouldResolveConsistentlyWith(runtimeClasspath.get()); |
297 | 318 | }); |
298 | | - productionRuntimeClasspath.setExtendsFrom(runtimeClasspath.getExtendsFrom()); |
299 | | - productionRuntimeClasspath.setCanBeResolved(runtimeClasspath.isCanBeResolved()); |
300 | | - productionRuntimeClasspath.setCanBeConsumed(runtimeClasspath.isCanBeConsumed()); |
301 | | - productionRuntimeClasspath.shouldResolveConsistentlyWith(runtimeClasspath); |
302 | 319 | } |
303 | 320 |
|
304 | 321 | private void configureDevelopmentOnlyConfiguration(Project project) { |
305 | | - Configuration developmentOnly = project.getConfigurations() |
306 | | - .create(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME); |
307 | | - developmentOnly |
308 | | - .setDescription("Configuration for development-only dependencies such as Spring Boot's DevTools."); |
309 | | - Configuration runtimeClasspath = project.getConfigurations() |
310 | | - .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
| 322 | + final var runtimeClasspath = project.getConfigurations().named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
| 323 | + final var developmentOnly = project.getConfigurations() |
| 324 | + .create(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME, (dev) -> { |
| 325 | + dev.setDescription("Configuration for development-only dependencies such as Spring Boot's DevTools."); |
| 326 | + dev.setCanBeConsumed(false); |
| 327 | + copyAttributes(runtimeClasspath, dev); |
| 328 | + }); |
| 329 | + runtimeClasspath.configure((r) -> r.extendsFrom(developmentOnly)); |
311 | 330 |
|
312 | | - runtimeClasspath.extendsFrom(developmentOnly); |
313 | 331 | } |
314 | 332 |
|
315 | 333 | private void configureTestAndDevelopmentOnlyConfiguration(Project project) { |
| 334 | + final var runtimeClasspath = project.getConfigurations().named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
316 | 335 | Configuration testAndDevelopmentOnly = project.getConfigurations() |
317 | | - .create(SpringBootPlugin.TEST_AND_DEVELOPMENT_ONLY_CONFIGURATION_NAME); |
318 | | - testAndDevelopmentOnly |
319 | | - .setDescription("Configuration for test and development-only dependencies such as Spring Boot's DevTools."); |
320 | | - Configuration runtimeClasspath = project.getConfigurations() |
321 | | - .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
322 | | - runtimeClasspath.extendsFrom(testAndDevelopmentOnly); |
323 | | - Configuration testImplementation = project.getConfigurations() |
324 | | - .getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME); |
325 | | - testImplementation.extendsFrom(testAndDevelopmentOnly); |
| 336 | + .create(SpringBootPlugin.TEST_AND_DEVELOPMENT_ONLY_CONFIGURATION_NAME, (tado) -> { |
| 337 | + tado.setDescription( |
| 338 | + "Configuration for test and development-only dependencies such as Spring Boot's DevTools."); |
| 339 | + tado.setCanBeConsumed(false); |
| 340 | + copyAttributes(runtimeClasspath, tado); |
| 341 | + }); |
| 342 | + runtimeClasspath.configure((it) -> it.extendsFrom(testAndDevelopmentOnly)); |
| 343 | + project.getConfigurations() |
| 344 | + .named(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME) |
| 345 | + .configure((testImplementation) -> testImplementation.extendsFrom(testAndDevelopmentOnly)); |
326 | 346 | } |
327 | 347 |
|
328 | 348 | private void configureSpringBootStarterTestToDependOnJUnitPlatformLauncher(Project project) { |
|
0 commit comments