Configure attributes on productionRuntimeClasspath

Previously, the productionRuntimeClasspath configuration was created
without any attributes. This caused problems with multi-project
dependency resolution as there was insufficient information for Gradle
to determine which variant of a dependency should be used by the
productionRuntimeClasspath configuration.

This commit updates the configuration to have three attributes, each
configured with the same values as those of Gradle's own
runtimeClasspathConfiguration.

Fixes gh-21549
This commit is contained in:
Andy Wilkinson 2020-05-26 12:51:33 +01:00
parent 069c31a074
commit ba23368440
3 changed files with 30 additions and 0 deletions

View File

@ -28,8 +28,13 @@ import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.attributes.Bundling;
import org.gradle.api.attributes.LibraryElements;
import org.gradle.api.attributes.Usage;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.ApplicationPlugin;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin;
@ -174,6 +179,12 @@ final class JavaPluginAction implements PluginApplicationAction {
.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
Configuration productionRuntimeClasspath = project.getConfigurations()
.create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
AttributeContainer attributes = productionRuntimeClasspath.getAttributes();
ObjectFactory objectFactory = project.getObjects();
attributes.attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME));
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.class, Bundling.EXTERNAL));
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
objectFactory.named(LibraryElements.class, LibraryElements.JAR));
productionRuntimeClasspath.setVisible(false);
productionRuntimeClasspath.setExtendsFrom(runtimeClasspath.getExtendsFrom());
runtimeClasspath.extendsFrom(developmentOnly);

View File

@ -146,6 +146,15 @@ class JavaPluginActionIntegrationTests {
.contains("developmentOnly exists = true");
}
@TestTemplate
void productionRuntimeClasspathIsConfiguredWithAttributes() {
assertThat(this.gradleBuild
.build("configurationAttributes", "-PconfigurationName=productionRuntimeClasspath", "-PapplyJavaPlugin")
.getOutput()).contains("3 productionRuntimeClasspath attributes:")
.contains("org.gradle.usage: java-runtime").contains("org.gradle.libraryelements: jar")
.contains("org.gradle.dependency.bundling: external");
}
private void createMinimalMainSource() throws IOException {
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example");
examplePackage.mkdirs();

View File

@ -25,3 +25,13 @@ task('configurationExists') {
println "${configurationName} exists = ${configurations.findByName(configurationName) != null}"
}
}
task('configurationAttributes') {
doFirst {
def attributes = configurations.findByName(configurationName).attributes
println "${attributes.keySet().size()} ${configurationName} attributes:"
attributes.keySet().each { attribute ->
println " ${attribute}: ${attributes.getAttribute(attribute)}"
}
}
}