gradlex-org / jvm-dependency-conflict-resolution

Gradle plugin to improve Dependency Conflict Detection and Resolution
http://gradlex.org/jvm-dependency-conflict-resolution/
Apache License 2.0
52 stars 14 forks source link

Failed to apply plugin with 'listenablefuture' library on the classpath #132

Closed ajax-gnatiuk-s closed 6 months ago

ajax-gnatiuk-s commented 6 months ago

I'm applying the plugins via buildSrc:

plugins {
    java
    id("org.gradlex.jvm-dependency-conflict-resolution")
    id("org.gradlex.jvm-dependency-conflict-detection")
}

(version 2.0)

Then I apply the convention to my root project.

When I try to assemble the project I receive the next exception:

     ...
Caused by: org.gradle.api.InvalidUserDataException: Cannot add capability com.google.guava:listenablefuture with version 1.0 because it's already defined with version 9999.0-empty-to-avoid-conflict-with-guava
    at org.gradle.internal.component.external.model.DefaultMutableCapabilitiesMetadata.addCapability(DefaultMutableCapabilitiesMetadata.java:45)
    at org.gradlex.jvm.dependency.conflict.detection.rules.CapabilityDefinitionRule.lambda$execute$0(CapabilityDefinitionRule.java:41)
    at org.gradle.internal.component.external.model.VariantMetadataRules$VariantAction.maybeExecute(VariantMetadataRules.java:213)
    at org.gradle.internal.component.external.model.VariantMetadataRules.applyCapabilitiesRules(VariantMetadataRules.java:110)
    at org.gradle.internal.component.external.model.DefaultConfigurationMetadata.getCapabilities(DefaultConfigurationMetadata.java:143)
    at org.gradle.internal.component.external.model.maven.RealisedMavenModuleResolveMetadata.transform(RealisedMavenModuleResolveMetadata.java:97)
    at org.gradle.api.internal.artifacts.dsl.DefaultComponentMetadataProcessor.realizeMetadata(DefaultComponentMetadataProcessor.java:89)
    at org.gradle.api.internal.artifacts.dsl.DefaultComponentMetadataProcessor.lambda$static$0(DefaultComponentMetadataProcessor.java:74)
    at org.gradle.internal.resolve.caching.CrossBuildCachingRuleExecutor.executeRule(CrossBuildCachingRuleExecutor.java:192)
    at org.gradle.internal.resolve.caching.CrossBuildCachingRuleExecutor.tryFromCache(CrossBuildCachingRuleExecutor.java:139)
    at org.gradle.internal.resolve.caching.CrossBuildCachingRuleExecutor.execute(CrossBuildCachingRuleExecutor.java:110)
    at org.gradle.api.internal.artifacts.dsl.DefaultComponentMetadataProcessor.processClassRuleWithCaching(DefaultComponentMetadataProcessor.java:241)
    ... 204 more

I've tried different workarounds but no luck, please help

jjohannes commented 6 months ago

I just found this as well yesterday. It's a bug with certain Guava versions. :/ Only workaround currently is to update to a newer Guava. I'll see that we do a patch release soon.

jjohannes commented 6 months ago

Actually I mixed things up. This should have solved the problem I had: https://github.com/gradlex-org/jvm-dependency-conflict-resolution/commit/5528ed576a611f2c94a618423da9cb3097fdd29e (this IS in the 2.0 release)

But you have it the other way around. I am also not sure how to reproduce it anymore.

Do you maybe still apply one of these older plugins as well? Which Guava version do you have on your classpath?

I am not sure where the capability with the 9999.0-empty-to-avoid-conflict-with-guava is added.

(We can do a general improvement to not get such errors at all, but I would like to reproduce this problem first)

ajax-gnatiuk-s commented 6 months ago

@jjohannes

Here minimal example where I was able to reproduce the issue: commit (branch)

plugins {
    id("org.gradlex.jvm-dependency-conflict-resolution") version "2.0"
    id("org.gradlex.jvm-dependency-conflict-detection") version "2.0"
}

dependencies {
     implementation(platform("com.google.cloud:spring-cloud-gcp-dependencies:5.2.0"))
     implementation("com.google.cloud:spring-cloud-gcp-starter-bigquery") //  <--- (1)
 }

(1) this has transitive dependency to com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava

\--- com.google.cloud:spring-cloud-gcp-starter-bigquery -> 5.2.0
     +--- com.google.cloud:spring-cloud-gcp-starter:5.2.0
     |    +--- com.google.cloud:spring-cloud-gcp-core:5.2.0
     |    |    +--- com.google.cloud:google-cloud-core:2.37.0
     |    |    |    +--- com.google.guava:guava:33.1.0-jre
     |    |    |    |    +--- com.google.guava:failureaccess:1.0.2
     |    |    |    |    +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
     |    |    |    |    +--- com.google.code.findbugs:jsr305:3.0.2
     |    |    |    |    +--- org.checkerframework:checker-qual:3.42.0
     |    |    |    |    +--- com.google.errorprone:error_prone_annotations:2.26.1
     |    |    |    |    \--- com.google.j2objc:j2objc-annotations:3.0.0
jjohannes commented 6 months ago

Thanks @ajax-gnatiuk-s. I now understand the problem. The plugin attempts to add the capability to com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava itself. This should not happen. So yes, it is a bug we introduced here.

Note: this situation exists, because other libraries like this one have the listenablefuture:9999.0-empty-to-avoid-conflict-with-guava as dependency although they shouldn't (only Guava itself should have it). But well...