Upgrading to 0.29.0-Beta introduces slf4j dependency hell: NoSuchMethodError
mgroth0 opened this issue · comments
Describe the bug
I'm using the sdk in gradle. That is, in a gradle "plugin" that shares a classpath with the Gradle API. Things were fine before, but suddenly after the new update I'm getting a NoSuchMethodError.
Expected behavior
No error
Current behavior
On an sdk method call, I get the following:
java.lang.NoSuchMethodError: 'boolean org.slf4j.Logger.isEnabledForLevel(org.slf4j.event.Level)'
at aws.smithy.kotlin.runtime.telemetry.logging.slf4j.Slf4JLoggerAdapter.isEnabledFor(Slf4jLoggerProvider.kt:38)
at aws.smithy.kotlin.runtime.telemetry.logging.CoroutineContextLogExtKt.log(CoroutineContextLogExt.kt:74)
at aws.smithy.kotlin.runtime.http.operation.OperationHandler.call(SdkOperationExecution.kt:398)
at aws.smithy.kotlin.runtime.http.operation.OperationHandler.call(SdkOperationExecution.kt:200)
at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt$execute$$inlined$withSpan$1.invokeSuspend(CoroutineContextTraceExt.kt:126)
at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt$execute$$inlined$withSpan$1.invoke(CoroutineContextTraceExt.kt)
at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt$execute$$inlined$withSpan$1.invoke(CoroutineContextTraceExt.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:167)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt.execute(SdkHttpOperation.kt:157)
at aws.sdk.kotlin.services.s3.DefaultS3Client.getObject(DefaultS3Client.kt:2169)
Steps to Reproduce
Creating a perfect reproducer seems very time consuming since it involves getting all the dependencies and build logic right. But essentially, it might be something like:
- Create a library distribution (folder of jars) that uses the SDK with version 0.29.0-Beta
- In
settings.gradle.kts
, load this folder of jars like so:
buildscript {
dependencies {
compile(fileTree(jarFolder))
}
}
- During gradle configuration, try to use the SDK.
- You might observe the error
Possible Solution
I'm not sure if the reproduction steps above would work, because its a sort of complex environment that I have and something might be missing. But in any case, I was able to figure out a few things while I was trying to debug this.
First of all, I added this to my code immediately before calling the sdk:
kotlin
println("Logger class source = ${org.slf4j.Logger::class.java.protectionDomain.codeSource.location}")
The output of that is:
Logger class source = file:/Users/matthewgroth/.gradle/wrapper/dists/gradle-8.2.1-all/d8pvvlun5bx6sdtwqhf8y9z4b/gradle-8.2.1/lib/slf4j-api-1.7.30.jar
This is interesting. Note the following:
- aws.smithy.kotlin:logging-slf4j2-jvm:0.23.0 has a runtime dependency on slf4j-api 2.0.6 (see: https://repo1.maven.org/maven2/aws/smithy/kotlin/logging-slf4j2-jvm/0.23.0/logging-slf4j2-jvm-0.23.0.pom)
- I made absolute sure that an updated slf4j-api jar was included on the class path.
slf4j-api-2.0.6
is in fact added as a compile dependency in my settings.gradle.kts right next to the sdk. - The method in question
isEnabledForLevel
is in fact only present inslf4j 2.x
. - I even tried adding
slf4j-nop
to the classpath, but this did not help. - I'm guessing that gradle loads up the
Logger
class from its own internalslf4j 1.x
jar before I even add the sdk.
At a bare minimum, having a way to disable logging completely to dodge this error in the meantime while a more robuse solution is eventually implemented would be great.
Context
Gradle Version: 8.2.1
Kotlin Version: 1.9.0
I was in sort of desperate need for the new update, because I kept running into #905
The above issue does have a workaround. I have implemented custom retry logic, which mostly works. But even this is failing sometimes. I'm very eager to try the solution that was seemingly implemented in 0.29.0
When I downgrade back to 0.28.0-beta, I dodge the slf4j dependency hell issue, but re-introduce the old java.io.EOFException: \n not found: limit=0 content=…
from the above referenced issue.
AWS Kotlin SDK version used
0.29.0-beta
Platform (JVM/JS/Native)
JVM
Operating System and version
Mac
I am testing 0.28.2-beta
right now. So far no errors. I will update this if I see any.
Thanks for the issue. Indeed in 0.29.0-beta
we took a dependency on SLF4J 2.x whereas previously we were on 1.x.
- What are you trying to do/create?
- It's not clear what the setup is here:
load this folder of jars like so:
, how are you managing dependencies? - Are you dependent on a specific SLF4J version or you just happen to use whatever the SDK does and there is a conflict now with gradle?
During gradle configuration, try to use the SDK.
- From this comment it would appear as if you are trying to use the SDK from a gradle script (and if I'm reading this right during the configure phase and not while executing a task).
I can provide some suggestions perhaps but it doesn't really look like an issue with the SDK, it's an issue with your classpath + gradle.
@aajtodd Thanks for the response and for the offer to provide some advice.
Sorry my original issue was so messy. I did not even want to try to make a reproducer because my project was so complex. But I did actually just try now, and luckily I was wrong. It was actually very simple and easy to reproduce!
https://github.com/mgroth0/aws-slf4j-dep-hell
There it is. If you clone and try to run any gradle command there, you should hopefully see the error.