[slf4j-dev] Re: using slf4j, nlog4j in Eclipse RCP

Heiner Westphal susp48 at verit.de
Tue Nov 29 13:20:25 CET 2005


Hello!

I really like the Idea of a transparent "logging central"
in eclipse, which accepts all sorts of logs
(at least slf4j,JCL,log4j) and provides these to the
framework of choice (for me  currently jdk14,log4j or
eclipse-own ErrorLog-plugin and  .metadata/.log and
possibly some TPTP/hyades-logging-adapter).

There has been research on centralizing logging in eclipse
in a friendly manner (every plugin may have its own logging
hierarchy... using log4j):
http://www-128.ibm.com/developerworks/library/os-eclog/

On the receiving end, we can right now put up a slf4j-plugin
providing access to the JCL-API and, of course, the SLF4j-API.
Possibly a log4j interceptor could be built as well, for
java.util.logging this would not be too easy, since we cannot
mask away jre-classes (or can we?).
On the sending end, all the slf4j-*.jars could be provided as
optional fragments to the plugin (so the name of the plugin is
always the same, regardless of where the logs will go).
Only one fragment allowed at any time of course.

If receiving and sending end could use the same logging-
framework, is one of the more interesting questions.
Could we use jcl104-over-slf4j together with slf4j-jcl.jar
or does the classloader go mad then? Logging-loop?
I'm getting a headache, so I better stop thinking about it :)

If this does not work, the receiving ends have to be
optional fragments as well, so you can drop them in case
of conflict.

If you need a use case for an slf4j eclipse plugin, here it is:

We (http://www.verit.de/) have an application (testing communication
   of systems of various kinds, simulating one or more of the actors)
   consisting of some eclipse-plugins using

- jetty(5 which uses JCL, going to 6 as soon as there is some
         spare time left). Jetty lives inside a plugin providing
        our core code simply as jars, without a plugin-class.
- hivemind (1.1 using JCL and not cleaned up with regard to classloading
       to be used inside another framework - classloader nightmares
       of the other kind / another story).
- org.eclipse.hyades.trace.sample needing hyades.logging.core using
   org.apache.jakarta_commons_logging (1.0.3)
    AND org.apache.jakarta_log4j_logging (1.2.8)
- our own classes (de.verit.peta.*) using slf4j, expecting some
   sort of log4j for Logger-configuration.
- jasperreports coming with JCL 1.0.2, but playing nice with 1.0.3
    or 1.0.4.

Below you can find an excerp of our adventures through the
second and third hell of classloading using 2 frameworks
not aware of each other and 3 logging mechanisms in an
OSGI-bundle environment.

Regards,

Heiner

P.S.: Through the logging hell and back:

1. First try: Using logging jars of various kinds inside the plugins
    (each provided the logging jars it used) lead to NoClassDefFounds
    with JCL which had found the log4j classes for one plugin, but
    could not get at them for another (from which we did not need to
    catch the logs anyways).
   result: BOOM

2. Second try: removing all jcl and log4j jars from the plugins and
    adding dependencies to the org.apache.jakarta_*_logging plugins.
    We tried to keep our beloved nlog4j giving us slf4j logging api
    with log4j config capabilities.
    And we left hivemind without log4j, to make sure it would not
    try to get at the nlog4j jar living in another plugin and
    not always accessible to hivemind.
    Trying to use JCL with AND without log4j at the same time is
    a particularly stupid idea (which we know now, but did not then).

    The JCL-plugin initialized using the classes from nlog4j via
    autodetection but could not get at them later on. When used from
    another plugin.
   result: BOOM

3. Third try:
   Build a new plugin containing jcl104-over-slf4j and nlog4j
   (from slf4j 1.0-rc1) and a simple config featuring a
   console-logger and setting the root loglevel to ERROR.

   Using jcl104-over-slf4j for jetty and nlog4j for the bridged
   jetty-logs and the de.verit.peta.* logs.
   hivemind (own plugin) and jasperreports (own plugin) got their
   dependencies adapted to stay away from the org.apache.jakarta*
   plugins and to use the newly built plugin instead.

   Sadly our examples-plugin depends on
   org.eclipse.hyades.trace.sample, which depends (in some steps)
   on the org.apache.jakarta_log4j_logging plugin.

   This got a bit confusing, since log4j does not try ugly things
   to make sure there is only one, there can be many log4js in one
   application, as long, as they are not accessible via the same
   classloader (Ceki please clarify, if I'm wrong here).

   When trying to reconfigure the root-logger from inside our
   application plugin, I saw, that it had log-level DEBUG!
   And adding a FileAppender did not seem to have any effect
   (the file was created, but stayed empty).
   What the f...rog is going on here?
   What I do not understand is, why I can get access to the root-logger
   of one log4j, and log to the other at the same time.
   Some OSGI-bundle-magic I suppose, since I accessed the log4j classes
   directly to configure them, but log via the slf4j-plugin, which
   has another version of the log4j classes.

   result: No logs! Having tamed JCL via jcl104-over-slf4j prevents
       the ClassNotFound/GameOver situation at least.


4. Fourth try: THIS ONE WORKS!
    Removed nlog4j from the slf4j-plugin and added slf4j-log4j12 instead
    as well as a dependency to the log4j-plugin.

    There is still the dependency to the JCL-plugin lurking around and
    making me nervous, but it does not seem to bite.

    For some reason re-exporting the plugin dependecy to the slf4j-plugin
    survived only one level. Trying to access the (reexported) log4j-
    plugin resulted in NoClassDefFoundError, if we did not import
    slf4j-plugin directly (having only one indirection of the log4j-
    plugin left).


Ceki Gülcü wrote:
> At 08:34 PM 11/23/2005, John Franey wrote:
> 
>> I don't think it is a stupid question.
>>
>> Flexibility.   A plug-in developed using SLF4J as an external plug-in 
>> can swap between SLF4J variants (jdk, log4j, nlog4j, custom).  A 
>> plug-in which embeds an SLF4J library will be bound to use the 
>> corresponding framework.   I think an RCP developer would prefer the 
>> former plug-in, only because the RCP developer can chose which 
>> framework the application would use.
>>
>> Memory/disk footprint:  If every plug-in embedded a logger library....
>>
>> Runtime confusion in Eclipse:  If every plug-in with a logging library 
>> exported it, Eclipse would non-deterministically select one, any one, 
>> to satisfy another plug-ins import.
>>
>> Those are main reasons.
> 
> 
> Makes sense. Thanks for the explanation.
> 
>>> Although you do not have to, you could license the code to slf4j.org 
>>> so that it could distribute your code. Alternatively, you could chose 
>>> to distribute your code on your own.
>>
>> I will think this over.   I currently leaning towards licensing the 
>> code for slf4j to distribute.  What does it mean to license the code, 
>> according to slf4j?  (My stupid question for the day).
> 
> 
> Very succinctly, the idea is similar if not identical to what the ASF 
> does. The ASF requires contributors to license their contribution to the 
> ASF in such a way that the ASF can legally redistribute it. For more 
> details, see http://apache.org/licenses/icla.txt in particular sections 
> 2, 4 and 5. (Replace "foundation" by "slf4j.org").
> 
> This is a very rough sketch, please do not hesitate to ask questions if 
> anything is unclear. Once you agree to the contributors license, we 
> could proceed to create an account for you.
> 




More information about the slf4j-dev mailing list