Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Jetty + Slf4j

Hi Hugues,

The webapp class loader filters org.slf4j.* classes (somewhat
counter-intuitively the syntax in serverClasses is actually "org.slf4j."  - that
trailing dot is all important). BTW, you can also do "-org.slf4j." and that
should remove the slf4j packages from the serverClasses.

Having upgraded to 1.5.8 of slf4j (I was using an old 1.3.1!) I can now reproduce the situation with the "SLF4J: Class path contains multiple SLF4J bindings." messages.

Looking at the slf4j source code, it seems to be just a warning message. The slf4j LoggerFactory retrieves, as a list of resources, all "org/slf4j/impl/StaticLoggerBinder.class" from the classloader as a check. As this resource will be present in the slf4j impl jar in jetty lib and the slf4j impl jar in the webapp's lib, it prints out the warning about multiple bindings. However, as far as my testing can determine, logging is unaffected by this, as jetty logging is still controlled by the server's classloader and the webapp's logging is still controlled by the webapp's classloader. I tested with slf4j-log4j12-1.5.8 and jetty logging still went to the slf4j-simple
logger from jsp2.0, whilst webapp logging  obeyed the log4.properties file.

cheers
Jan

Hugues Malphettes wrote:
On Tue, Dec 8, 2009 at 5:32 PM, Jan Bartel <janb@xxxxxxxxxxx> wrote:
Hi Hugues,

The default setup for a webapp context is that a webapp will be
prevented from loading the slf4j classes from the server's
classpath, *but a webapp can provide their own copy of these jars
in WEB-INF/lib*.
I've just tested this to confirm it works with 6.1.22 (and jdk1.5 and
jdk1.4).
If I use the slf4j apis in a webapp, and don't provide the slf4j-api and an
slf4j impl jar in my webapp, I get ClassNotFound exceptions. However,
if I do provide these jars, then my webapp works happily and the jetty
logging is unaffected.

Thanks for the explanation.

In my experience when you provide the org.slf4j.impl (the log4j
adapter in the case of Julio) you do get a warning about multiple
bindings for slf4j: I suspected that slf4j-api in the webapp will
locate the impl inside the webapp and the impl inside jsp-2.0 as jetty
does not filter org.slf4j.impl like it does for org.slf4j ?


Note that I specifically mention the version of the jdk. This is simply
because with jdk < 1.5, the server path will have no slf4j jars on it
anyway, because they are only present in $JETTY-HOME/lib/jsp-2.0, which
start.jar only puts on the classpath iff jdk < 1.5.

So in short, you're absolutely right that the default setup guarantees
isolation of logging between a webapp and the server. An app should be able
to put their own copies of slf4j into their WEB-INF/lib and it should just
work. However, if they want to, they can take the org.slf4j.
package out of the list of serverClasses for a webapp and they should
be able to see and use the jars from the server's classpath.

BTW looking at your jetty6-web.xml file, I don't see anything related to the
slf4j package?

Sorry for the confusion: the file should just remove org.slf4j from
the filtered packages to achieve its stated goal.
I should have refactored the file. I know for a fact that it works and
that removing it will break the app.

Cheers,
Hugues.

cheers
Jan

Hugues Malphettes wrote:
Hi Julio,
We faced this issue with jetty6 with the standard distribution.
We chose to do this:
1- remove *slf4j*, commons-logging, log4j jars from the webapp.
2- add a jetty6-web.xml inside the WEB-INF of our web-application that
contains this xml:
<?xml version="1.0"  encoding="ISO-8859-1"?>
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
   <Set name="serverClasses">
       <Array type="java.lang.String">
           <Item>-org.mortbay.jetty.plus.jaas.</Item>
           <Item>org.mortbay.jetty.</Item>
       </Array>
   </Set>
</Configure>

Jetty6 does something special with the webapp classloader that
prevents a web-application to access the org.slf4j.* classes that are
provided by the server's classloader. I have not really understood the
reason for this; although I am guessing it is to support some
isolation of the logging for each webapp.
Adding this jetty6-web.xml will basically let your webapp access the
shared slf4j. slf4j will locate the other *slf4j* jars in the server's
classes loader.


This setup will enforce "centralized" logging in jetty6:
the configuration of the logging is done in one single place:
${jetty.home}/resources/log4j.properties (or logback.xml)
for all web-applications.
You should add log4j.jar inside the shared libraries (or
logback-core+logback-classic). In the standard distribution of jetty6
that would be inside ${jetty.home}/lib/ext.
I am not sure where it is in the debian distribution.


Jetty7 will support configuration of centralized logging as an option
and I believe will not have this kind of difficult issue anymore.

I hope this helps,
Hugues.

On Tue, Dec 8, 2009 at 10:39 AM, Julio Viegas
<julioviegas@xxxxxxxxxxxxxxx> wrote:
Hello Diego,

 How are you starting Jetty? I mean, can you check your Jetty's JVM
classpath setting?

 I suspect "jar:file:/usr/share/java/slf4j-simple-1.5.8.jar" is
inside your $CLASSPATH or something like that...

Rgrds,
JV -- julioviegas.com

On Tue, Dec 8, 2009 at 16:26, Diego Plentz <diego@xxxxxxxxxx> wrote:
Hey guys,
I'm using jetty 6.1.x installed through apt-get in a Ubuntu box. When I
deploy my application, I have a problem with slf4j. If I deploy my war
with
slf4j-log4j12-1.5.8.jar, I have this message:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in

[jar:file:/usr/share/java/slf4j-simple-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in

[jar:file:/var/cache/jetty/Jetty_0_0_0_0_8080_suporte_promotor.war___suporte.promotoronline.com.br_ivstzq/webapp/WEB-INF/lib/slf4j-log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an
explanation.
But, if I remove the jar from the war file, I have a
NoClassDefFoundError:
Caused by: java.lang.NoClassDefFoundError:
org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:223)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:120)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:269)
....
What is the correct behavior?
--
http://plentz.org
http://twitter.com/plentz

_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users


_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users

_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users
--
Jan Bartel, Webtide LLC | janb@xxxxxxxxxxx | http://www.webtide.com
_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users


--
Jan Bartel, Webtide LLC | janb@xxxxxxxxxxx | http://www.webtide.com


Back to the top