kroxylicious icon indicating copy to clipboard operation
kroxylicious copied to clipboard

Kroxylicious >= 0.17.0 no longer tolerates SLF4j1 on the runtime classpath

Open k-wall opened this issue 2 months ago • 3 comments

Raising for informational purposes. I don't actually think there is a Kroxylicious defect.

At runtime, Kroxylicious 0.16.0 and less would tolerate SLF4j v1 on the classpath, rather than v2. I don't believe this was actually ever the intent. The project declared dependency was SLF4j v2 since before the v0.1.0 release (a69806d7c7d0afaff61aedadfefc4293b95be95b).

I became aware of this when I tested the 0.17.0 release with https://github.com/andreaTP/kroxylicious-wasm. It works with Kroxylicious 0.16.0 and earlier but failed (hanging ITs) with 0.17.0.

025-10-28 14:32:32 <multiThreadIoEventLoopGroup-5-1> DEBUG io.netty.channel.AbstractChannelHandlerContext:292 - An exception was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.lang.NoSuchMethodError: 'org.slf4j.spi.LoggingEventBuilder org.slf4j.Logger.atDebug()'
	at io.kroxylicious.proxy.internal.ProxyChannelStateMachine.onClientActive(ProxyChannelStateMachine.java:261)
	at io.kroxylicious.proxy.internal.KafkaProxyFrontendHandler.channelActive(KafkaProxyFrontendHandler.java:178)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:220)
	at io.kroxylicious.proxy.internal.KafkaProxyInitializer$1.lambda$channelActive$0(KafkaProxyInitializer.java:115)
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
	at java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:950)
	at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2372)
	at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:144)
	at io.kroxylicious.proxy.internal.KafkaProxyInitializer$1.channelActive(KafkaProxyInitializer.java:108)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:220)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelActive(DefaultChannelPipeline.java:1417)
	at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:862)
	at io.netty.channel.AbstractChannel$AbstractUnsafe$2.operationComplete(AbstractChannel.java:391)
	at io.netty.channel.AbstractChannel$AbstractUnsafe$2.operationComplete(AbstractChannel.java:374)
	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:603)
	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:570)
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:505)
	at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:649)
	at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:638)

It is the position of the kafka-client dependeny in its pom that cause the issue.

https://github.com/andreaTP/kroxylicious-wasm/blob/main/pom.xml#L53

kafka-client has a transitive dependency on SLF4jv1, and as it appears before the kroxylicious-integration-test-support (which transitively brings in kroxylicious-runtime and SLF4j v2), Maven is letting SLF4jv1 prevail.

This causes the kroxylicious-wasm ITs to fail. The solution is to re-order the dependencies.

kroxylicious-runtime correctly announces its dependency on the SLF4j v2, so I don't think there is actually a Kroxylicious defect here.

k-wall avatar Oct 28 '25 17:10 k-wall

If it turns out we see users falling into this trap, maybe we add code to Kroxylicious to check the SLF4j v1 and fail with a clear error message.

k-wall avatar Oct 28 '25 18:10 k-wall

So this is a runtime classpath issue?

SamBarker avatar Oct 28 '25 19:10 SamBarker

So this is a runtime classpath issue?

Yes.

The trap is the fact that kafka-client has a transitive dependency on SLF4j v1. If the user adds this to their classpath above the kroxylicious deps, SLF4j v1 will take precedence. That's what the WASM project did (before I fixed it). It was a bit obscure to debug. The tests were seemingly hanging on the create topic future. It wasn't until I raised the logging level that the classpath issue become apparent.

k-wall avatar Oct 28 '25 19:10 k-wall