[GRADLE-897] Gradle's SLF4J bindings are visible to webapp run with the Jetty plugin Created: 08/Apr/10  Updated: 22/Nov/16  Resolved: 22/Nov/16

Status: Resolved
Project: Gradle
Affects Version/s: 0.9
Fix Version/s: None

Type: Bug
Reporter: Jeppe Nejsum Madsen Assignee: Unassigned
Resolution: Won't Fix Votes: 21


 Description   

Using jettyRun with a webapp that contains SLF4J bindings causes warnings to be printed since Gradle's bindings are also visible to the webapp:

:jettyRunSLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/local/share/java/gradle/lib/logback-classic-0.9.18.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/jeppe/.gradle/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.5.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

This may cause unpredictable logging since it is not clear which logging backend is being used....



 Comments   
Comment by Wolfgang Schell [ 26/May/11 ]

I see the same behavior.

Comment by Thomas Baur [ 13/Jul/11 ]

This causes some headaches if the version of slf4j that is requested in the project WAR itself is different. A wrong version of the static facade may be called:

java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)

This is due to a mix of classes from slf4j 1.6.1 (used in the project) and 1.4.3 (probably), used internally in logback-classic-0.9.24.jar, which resides in gradle/lib.

Comment by island chen [ 08/Sep/11 ]

I see the same behavior too.

According to http://www.slf4j.org/codes.html#multiple_bindings, that means "SLF4J will still bind with the first framework it finds on the class path" – which in gradle will always be StaticLoggerBinder, and this is definitely what we want.

Comment by Jeremy Judeaux [ 29/Dec/11 ]

I see the same behaviour, and the face that it uses StaticLoggerBinder is definitely not what I want. I'm expecting that slf4j uses the binding to LOG4J, not the one to Logback.

This bug seems to be the consequence of this Jetty bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=297421
Upgrading to Jetty 7 should fix it, but I don't know how to do that.

Comment by Christian Lipp [ 21/Feb/13 ]

I am not sure if this belongs to this issue, but I would like to mention it (just to make sure):

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/clipp/.gradle/caches/artifacts-15/filestore/org.slf4j/slf4j-log4j12/1.7.2/jar/7539c264413b9b1ff9841cd00058c974b7cd1ec9/slf4j-log4j12-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/springsource/sts-3.1.0.RELEASE/plugins/org.springsource.ide.eclipse.gradle.core_3.1.0.201210040512-RELEASE/lib/slf4j-simple-1.6.6.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 [org.slf4j.impl.Log4jLoggerFactory]

A similar problem (or the same) occurs when using slf4j for a project with a Gradle build and using the STS Gradle plugin.

Comment by chen [ 07/Apr/13 ]

I see the same behaviour... +1024,i wonder how can i solve this problem?
In maven it can be:
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
But gradle?

Comment by Tom Dunstan [ 21/Aug/13 ]

+1 I just hit this.

If I leave logback out of the webapp, it complains with:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

but if I add logback-classic in as a runtime dependency, I get:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/tom/.gradle/wrapper/dists/gradle-1.7-bin/2g3i7gan25uopmtc0lnjb1l9ff/gradle-1.7/lib/logback-classic-1.0.9.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/tom/.gradle/caches/artifacts-26/filestore/ch.qos.logback/logback-classic/1.0.13/jar/6b56ec752b42ccfa1415c0361fb54b1ed7ca3db6/logback-classic-1.0.13.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]

So it seems that there's no way I can get SLF4J to be quiet.

Comment by Matt Hauck [ 23/Aug/13 ]

I think the only way to get around this is to have the jetty/tomcat plugins fork so that the webapp runs in a separate jvm that does not contain gradle's own classpath.

Comment by Tom Dunstan [ 24/Aug/13 ]

Well, without knowing much about Gradle's internals, there are a couple of potential solutions that servlet engines and app servers have used over the years:

  • make the slf4j that gradle uses internally use a different package name. e.g. prefix with org.gradle.internal or something like that.
  • load most of gradle's functionality in a classloader which is a child of the main class loader, then load e.g. jetty in a child classloader of the main classloader rather than a child of gradle's classloader.

Maybe logging needs to be in the root classloader for error reporting problems, though...

Comment by Matt Hauck [ 26/Aug/13 ]

In case it benefits anyone, I made a simple tomcat plugin that forks into a new process to avoid issues like this. Something similar could easily be done with jetty. https://gist.github.com/matthauck/6338633

Comment by Benjamin Muschko [ 15/Nov/16 ]

As announced on the Gradle blog we are planning to completely migrate issues from JIRA to GitHub.

We intend to prioritize issues that are actionable and impactful while working more closely with the community. Many of our JIRA issues are inactionable or irrelevant. We would like to request your help to ensure we can appropriately prioritize JIRA issues you’ve contributed to.

Please confirm that you still advocate for your JIRA issue before December 10th, 2016 by:

  • Checking that your issues contain requisite context, impact, behaviors, and examples as described in our published guidelines.
  • Leave a comment on the JIRA issue or open a new GitHub issue confirming that the above is complete.

We look forward to collaborating with you more closely on GitHub. Thank you for your contribution to Gradle!

Comment by Jochen Kemnade [ 16/Nov/16 ]

Since the jetty plugin is deprecated, I guess this is a WONTFIX.

Comment by Benjamin Muschko [ 22/Nov/16 ]

The Jetty plugin has been deprecated and will be removed with Gradle 4.0. Consequently, we are not planning to fix this issue anymore.

Generated at Wed Jun 30 11:41:43 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.