slf4j dependency hell: If slf4j2 is present on the classpath, but the LoggerFactory returns a slf4j1 logger, we get a java.lang.NoSuchMethodError
NatanLifshitz opened this issue · comments
Describe the bug
AWS SDK for Kotlin can't be used in a Gradle script.
Expected behavior
No Crash
Current behavior
Trying to use the sdk in gradle, i get:
Caused by: java.lang.NoSuchMethodError: 'org.slf4j.spi.LoggingEventBuilder org.slf4j.Logger.atLevel(org.slf4j.event.Level)'
at aws.smithy.kotlin.runtime.telemetry.logging.slf4j.Slf4j2xLoggerAdapter.atLevel(Slf4j2xLoggerAdapter.kt:18)
at aws.smithy.kotlin.runtime.telemetry.logging.CoroutineContextLogExtKt.log(CoroutineContextLogExt.kt:77)
at aws.smithy.kotlin.runtime.telemetry.logging.CoroutineContextLogExtKt.warn(CoroutineContextLogExt.kt:135)
Steps to Reproduce
Any gradle buildscript that uses aws sdk for kotlin should have this issue
Possible Solution
This check is not good enough:
private val useSlf4j2x = try {
Class.forName("org.slf4j.spi.LoggingEventBuilder")
true
} catch (ex: ClassNotFoundException) {
LoggerFactory.getLogger(Slf4jLoggerProvider::class.java).warn("falling back to SLF4J 1.x compatible binding")
false
}
It should instead do something like this:
override fun getOrCreateLogger(name: String): Logger {
val sl4fjLogger = LoggerFactory.getLogger(name)
try{
sl4fj.atLevel(...)
return Slf4j2xLoggerAdapter(sl4fjLogger)
}
catch(e: NoSuchMethodError) {
return Slf4j1xLoggerAdapter(sl4fjLogger)
}
}
And cache the check if you want.
Context
No response
AWS Kotlin SDK version used
0.32.5-beta
Platform (JVM/JS/Native)
JVM
Operating System and version
Windows 11
Closed by awslabs/smithy-kotlin#981. Thanks again for contributing this fix!
⚠️ COMMENT VISIBILITY WARNING⚠️
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.