logging-capabilities
logging-capabilities copied to clipboard
Regression in Gradle 6.7+ using selectXxx API (not with enforceXxx)
Working on adding proper multi version testing (#7), two tests fail in all versions of Gradle starting with 6.7-rc-1 (I might have not tested all of them, but most I think).
See https://github.com/tbroyer/logging-capabilities/actions/runs/2253199669
can select logback in case of conflict (with extra [org.slf4j:slf4j-jcl:1.7.27, org.slf4j:slf4j-log4j12:1.7.27])
* What went wrong:
Execution failed for task ':doIt'.
> Could not resolve all files for configuration ':runtimeClasspath'.
> Could not resolve org.slf4j:slf4j-simple:1.7.27.
Required by:
project :
> Module 'org.slf4j:slf4j-jcl' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-log4j12:1.7.27(runtime)]
> Could not resolve org.slf4j:slf4j-jcl:1.7.27.
Required by:
project :
> Module 'org.slf4j:slf4j-jcl' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-log4j12:1.7.27(runtime)]
> Could not resolve org.slf4j:slf4j-log4j12:1.7.27.
Required by:
project :
> Module 'org.slf4j:slf4j-jcl' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-log4j12:1.7.27(runtime)]
> Could not resolve ch.qos.logback:logback-classic:1.2.3.
Required by:
project :
> Module 'org.slf4j:slf4j-jcl' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-simple:1.7.27(runtime), org.slf4j:slf4j-log4j12:1.7.27(runtime)]
can select logback in case of conflict (with extra [org.slf4j:slf4j-log4j12:1.7.27])
* What went wrong:
Execution failed for task ':doIt'.
> Could not resolve all files for configuration ':runtimeClasspath'.
> Could not resolve org.slf4j:slf4j-simple:1.7.27.
Required by:
project :
> Module 'org.slf4j:slf4j-log4j12' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime)]
> Could not resolve org.slf4j:slf4j-log4j12:1.7.27.
Required by:
project :
> Module 'org.slf4j:slf4j-log4j12' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime)]
> Could not resolve ch.qos.logback:logback-classic:1.2.3.
Required by:
project :
> Module 'org.slf4j:slf4j-log4j12' has been rejected:
Cannot select module with conflict on capability 'dev.jacomet.logging:slf4j-impl:1.0' also provided by [org.slf4j:slf4j-simple:1.7.27(runtime)]
Adding logs to the getCapabilitiesResolutionAction
, we can see it's called several times with different sets of candidates (no idea if this is the actual problem, I haven't checked the tests that pass)
resolution.withCapability(dev.jacomet.logging:slf4j-impl)
- candidate: org.slf4j:slf4j-simple:1.7.27
- candidate: org.slf4j:slf4j-jcl:1.7.27
resolution.withCapability(dev.jacomet.logging:slf4j-impl)
- candidate: org.slf4j:slf4j-simple:1.7.27
- candidate: org.slf4j:slf4j-jcl:1.7.27
- candidate: org.slf4j:slf4j-log4j12:1.7.27
resolution.withCapability(dev.jacomet.logging:slf4j-impl)
- candidate: org.slf4j:slf4j-simple:1.7.27
- candidate: org.slf4j:slf4j-jcl:1.7.27
- candidate: org.slf4j:slf4j-log4j12:1.7.27
- candidate: ch.qos.logback:logback-classic:1.2.3
-> select(ch.qos.logback:logback-classic:1.2.3(runtime))
Diff of the added logging instructions
diff --git a/src/functionalTest/groovy/dev/jacomet/gradle/plugins/logging/AbstractLoggingCapabilitiesPluginFunctionalTest.groovy b/src/functionalTest/groovy/dev/jacomet/gradle/plugins/logging/AbstractLoggingCapabilitiesPluginFunctionalTest.groovy
index 2e28e26..a6ce567 100644
--- a/src/functionalTest/groovy/dev/jacomet/gradle/plugins/logging/AbstractLoggingCapabilitiesPluginFunctionalTest.groovy
+++ b/src/functionalTest/groovy/dev/jacomet/gradle/plugins/logging/AbstractLoggingCapabilitiesPluginFunctionalTest.groovy
@@ -42,7 +42,7 @@ abstract class AbstractLoggingCapabilitiesPluginFunctionalTest extends Specifica
.withGradleVersion(testGradleVersion.version)
.withPluginClasspath()
.withProjectDir(testFolder.toFile())
- .withArguments(args + ["-s"])
+ .withArguments(args + ["-s", "--info"])
}
void withBuildScript(String content) {
diff --git a/src/main/java/dev/jacomet/gradle/plugins/logging/extension/LoggingCapabilitiesExtension.java b/src/main/java/dev/jacomet/gradle/plugins/logging/extension/LoggingCapabilitiesExtension.java
index 2785179..12c09cb 100644
--- a/src/main/java/dev/jacomet/gradle/plugins/logging/extension/LoggingCapabilitiesExtension.java
+++ b/src/main/java/dev/jacomet/gradle/plugins/logging/extension/LoggingCapabilitiesExtension.java
@@ -17,6 +17,8 @@ import org.gradle.api.artifacts.dsl.DependencyHandler;
* Project extension that enables expressing preference over potential logging capabilities conflicts.
*/
public class LoggingCapabilitiesExtension {
+ private final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LoggingCapabilitiesExtension.class);
+
private final ConfigurationContainer configurations;
private final DependencyHandler dependencies;
private final Runnable alignmentActivation;
@@ -463,15 +465,17 @@ public class LoggingCapabilitiesExtension {
private Action<CapabilitiesResolution> getCapabilitiesResolutionAction(String capabilityId, ExternalDependency target, String because) {
return resolution -> resolution.withCapability(capabilityId, details -> {
+ logger.info("resolution.withCapability({})", capabilityId);
details.getCandidates().stream().filter(candidate -> {
ComponentIdentifier id = candidate.getId();
+ logger.info(" - candidate: {}", id);
if (!(id instanceof ModuleComponentIdentifier)) {
return false;
}
ModuleComponentIdentifier moduleId = (ModuleComponentIdentifier) id;
return moduleId.getGroup().equals(target.getGroup())
&& moduleId.getModule().equals(target.getName());
- }).findFirst().ifPresent(candidate -> details.select(candidate).because(because));
+ }).findFirst().ifPresent(candidate -> { logger.info(" -> select({})", candidate); details.select(candidate).because(because); });
});
}
This is possibly a regression in Gradle itself, but it manifests itself only in this particular test (the only one not using enforceXxx
API calls, but selectXxx
instead)
Damn, that's not good. I am not sure when I'll have the time to follow up properly on this, especially if a change is needed on the Gradle side.
This is caused by a capability conflict ordering issue in Gradle.
A workaround is to make sure that the dependency that resolves the conflict is seen before any dependency it conflicts with.
I am closing this as the issue is in Gradle itself. I have been working on fixing those issues. I am hoping the changes can be released with Gradle 8.11.