3

I'm trying to embed Jetty server into my automated tests so I've added the following dependency in my project:

<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-servlet</artifactId>
  <version>7.6.13.v20130916</version>
  <scope>test</scope>
</dependency>

I'm using Jetty 7 because the Web app uses Java 6, Servlet 2.5.

However when I try to start embedded Jetty server, I get:

java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V
    at org.eclipse.jetty.util.log.JettyAwareLogger.log(JettyAwareLogger.java:607)
    at org.eclipse.jetty.util.log.JettyAwareLogger.warn(JettyAwareLogger.java:431)
    at org.eclipse.jetty.util.log.Slf4jLog.warn(Slf4jLog.java:69)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.setFailed(AbstractLifeCycle.java:204)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:74)

I've been trying to figure out what's wrong but none of the steps I've taken so far addresses the issue. Here's a list of what I've done so far:

  • Trace transitive dependencies to search for incompatible versions of slf4j-api
  • Try out different versions of slf4j-api (1.5.11, 1.6.1, 1.6.4, 1.7.5)
  • Looked into the some sources of Jetty 7 particularly the pom.xml and found that there's a dependency to slf4j 1.6.1
  • Looked into this similar question and got null when trying to print org.slf4j.spi.LocationAwareLogger, and org.slf4j.Marker

I hope someone can offer a fresh insight into this issue. Thanks.

Community
  • 1
  • 1
Psycho Punch
  • 6,418
  • 9
  • 53
  • 86

2 Answers2

4

I bet you've faced a compatibility problem between sl4j jars. Try examinating mvn dependency:tree output of your final artifact. Maybe you have two different versions of some sl4j jar and you cannot predict which loads first. Try to equalize all sl4j versions.


OP: Please refer to the documentation on how I resolved this.

Community
  • 1
  • 1
madhead
  • 31,729
  • 16
  • 153
  • 201
  • I've even made it to the point where there's absolutely no slf4j in the dependency tree, to ensure that when I add it specifically, all transitive dependencies have been excluded completely. – Psycho Punch Sep 28 '13 at 22:59
  • 1
    If there are no `sl4j` jars at all, then you'd got `NoClassDefFoundError` as `JettyAwareLogger` contains references to `sl4j` SPI classes. So, the classes are present at runtime. Where are they came from? Maybe it's you container `lib` folder? Or maybe you depend on a repackaged jar, which already contains `sl4j` classes? – madhead Sep 28 '13 at 23:07
  • Do you know of any way I could verify this? What I've done so far is, since I'm using Eclipse, import `LocationAwareLogger` in any class, then try to trace it to check if it's getting imported from the `slf4j` jar in the build path. I can't import it if I don't have any dependency to `slf4j`, but as you've noticed, I'm not getting a `NoClassDefFoundError`, which I've also been trying to deliberately raise. – Psycho Punch Sep 28 '13 at 23:25
  • 1
    **1** Start JVM with `-verbose:class` option _or_ **2** While in Eclipse debug stop on any breakpoint and show `Display` view. Type `org.slf4j.spi.LocationAwareLogger.class.getResource(org.slf4j.spi.LocationAwareLogger.class.getSimpleName() + ".class")` in it, select and press `Display Result of Evaluating Selected Text`. You'll see where the class come from. – madhead Sep 28 '13 at 23:45
  • 1
    If using jetty standalone, use `$ java -jar start.jar --version` and see the server classpath. Then look at your webapp's `WEB-INF/lib` tree. Finally, set the [`jetty.dump.start`](https://github.com/eclipse/jetty.project/blob/master/jetty-distribution/src/main/resources/start.ini#L77) in your standalone jetty to `true` to see a dump of the webapp classpath. – Joakim Erdfelt Sep 29 '13 at 14:14
  • I've got this issue addressed. Thanks. Refer to the documentation of the steps I took to resolve it: http://stackoverflow.com/a/19133662/404604. – Psycho Punch Oct 02 '13 at 09:19
  • can you help on this http://stackoverflow.com/questions/44091042/nosuchmethoderror-org-slf4j –  May 21 '17 at 04:33
3

The information on madhead's answer was very helpful but I'm going to document the details of what I've done for the sake for others who (will) encounter the same problem.

As the answer mentioned suggested, it was a problem with slf4j jars. To verify I did the following:

  1. Define exclusion on all dependencies that have dependencies on slf4j.
  2. Follow option 2 from this suggestion.
    • I wrote a unit test that just sysout's a String of my choosing, and define a breakpoint at that line.
    • Then I debug the test as JUnit test, and open the Display view
    • I needed to re-run it because Display Result of Evaluating Selected Text was disabled at first for some reason.
    • I found out that the runtime still refers to the 1.5.8 version of slf4j that was still being added into the classpath regardless if I specified exclusion for it.
  3. The project I'm working on depends on another project I'm also working on (it's a multi-Maven project project), which specified dependency to slf4j-jdk14 1.5.8, so I just updated it to 1.6.1.
    • I had to specify exclusion of slf4j-api under slf4j-jdk14 1.6.1 because it was referring to version 1.5.8, and add direct dependency to slf4j-api 1.6.1.
Community
  • 1
  • 1
Psycho Punch
  • 6,418
  • 9
  • 53
  • 86