[slf4j-dev] slf4j-osgi-api module

Hugues Malphettes hmalphettes at intalio.com
Thu Nov 26 18:32:03 CET 2009


On Thu, Nov 26, 2009 at 2:25 AM, Ceki Gülcü <ceki at qos.ch> wrote:
> Hello Hugues,
>
Hi!

Thanks for your interest in this experiment to get rid of the cyclic
dependency between slf4j-api and a bundle that provides an slf4j
implementation (bug #75).
>
> From what I could gather looking at the slf4j-api-osgi module, it
> looks like the slf4j-api-osgi module is responsible for binding
> slf4j-api with the underlying logging framework using the resolution
> functionality offered by OSGi. Given that slf4j-api-osgi module itself
> exports the org.slf4j.impl package, I was wondering how you were going
> to avoid recursing endlessly into slf4j-api-osgi or mistakenly export
> the org.slf4j.impl package found in slf4j-api-osgi instead of a
> real/desired implementation. slf4j-api-osgi avoids that undesirable
> predicament by exporting the o.s.impl package only if the exporting
> bundle is not itself. It also registers listeners in case the desired
> bundle is installed later on. Nice.

Thanks!

I tested this scenario to make sure the listeners are working as expected:
- start everything with logback-classic
- do some logging: loggers are provided by logback-classic
- stop logback-classic.
- get a new Logger returns the NOP-logger
- start logback-classic again
- getting a new logger return loggers provided by logback classic again.

>
> However, I still don't see what happens if the slf4j-api-osgi is
> exported by another bundle *before* the slf4j-api-osgi bundle is
> installed and before it has a chance to act.

OSGi will only start a bundle once all its dependencies are resolved
as bundles and those are started.
As all bundles that provide o.s.impl import the package o.slf4j; it is
guaranteed that slf4j-api is installed first before them.

slf4j-api-osgi bundle is a fragment hosted by slf4j-api.
When slf4j-api is installed by the OSGi container the slf4j-api-osgi
is "attached" to slf4j-api.
The OSGi spec says that fragments are not started, they are "attached"
to their host bundle.
Hence when slf4j-api is started we also have slf4j-api-osgi acting inside it.
The org.slf4j.impl package provided by slf4j-api-osgi is placed in the
very same classloader than org.slf4j.Logger

So when org.slf4j.LoggerFactory imports
org.slf4j.impl.StaticLoggerBinder it finds the one provided by
slf4j-api-osgi.

There is another way to achieve the exact same situation: place the
classes of slf4j-api-osgi as a jar embedded inside slf4j-api. It is
taken into account only by osgi and it would save us having to carry a
new jar for the OSGi support.

>
> Much more importantly, I am worryingly missing the big picture. Even
> if the org.slf4j.impl is exported according to our wishes, how is the
> org.slf4j package imported and by who? In other words, how does client
> code wishing to use the org.slf4j.Logger class get hold of it and what
> is the relationship between that client code and OSGi?

Client bundles that depend on slf4j state in their manifest:
      Import-Package: org.slf4j
The osgi container resolves this into a dependency on slf4j-api and
everything works on the client side.

On the logger implementation side: we need logback-classic or another
bundle that provides o.s.impl to be set to start automatically. slf4j
logs with NOPLogger until logback-classic is started

Let me know if this makes sense,
Cheers,
Hugues

>
> Many thanks in advance for your response,
>
> --
> Ceki
>
> ps. I am CCing dev at slf4j.org so that others can follow the discussion.
>


More information about the slf4j-dev mailing list