Avoiding NoClassDefFoundError errors when using slf4j-test with Logback and Maven

As I wrote about in Testing Your SLF4J Logs, the slf4j-test, library is awesome for allowing us to add tests for our logs.

But today I hit a couple of NoClassDefFoundErrors today when setting this up with Logback on a Spring Boot project today, and it was a unobvious how to solve this - so I thought I'd share what fixed it.

Starting with the maven-surefire-plugin configuration as:

<!-- ... -->
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.2</version>
</plugin>
<!-- ... -->

Left me with the usual warnings in my logs, as slf4j-test needs to be the only implementation:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/jamie/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/jamie/.m2/repository/uk/org/lidalia/slf4j-test/1.2.0/slf4j-test-1.2.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

I then tried to exclude the logback package from my configuration, and ended up with one of two exceptions:

java.lang.NoClassDefFoundError: ch/qos/logback/classic/turbo/TurboFilter
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.turbo.TurboFilter

Or:

java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.core.joran.spi.JoranException

It turns out the fix was to exclude both packages:

<!-- ... -->
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.2</version>
  <classpathDependencyExcludes>
    <classpathDependencyExcludes>ch.qos.logback:logback-core</classpathDependencyExcludes>
    <classpathDependencyExcludes>ch.qos.logback:logback-classic</classpathDependencyExcludes>
  </classpathDependencyExcludes>
</plugin>
<!-- ... -->

And then our tests run correctly!

One caveat of this is I've not yet found a way of getting it working so I can use logstash-logback-encoder. This could be related to a Spring Boot defect.

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #testing #java #slf4j.

This blog post is 100% human-written, and has nothing derived from LLMs (be it code, editorial support or prose).

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.