[slf4j-dev] SL4FJ light: ad-hoc bindings for friendlier OSGi/IoC integration

Matthew Bishop Matthew.Bishop at elasticpath.com
Mon Oct 15 19:20:38 CEST 2012


Simon, you have spent considerable time on this proposal. I agree that it would be worthwhile to investigate further.

My experience with inject vs. static binding to loggers is mixed, meaning some people won't, or cannot, accept the injected approach. We need to have both methods of acquiring logger instances.

I have a Guice injection module that I can contribute. I think you have something similar for Spring. Interested in putting something together as an injection starting point?

--
Matthew Bishop
Senior Product Architect
Elastic Path Inc.

On 2012-10-15, at 4:53 AM, "Simon Chemouil" <schemouil+slf4j at gmail.com> wrote:

> Hi,
>
> I am in the process of choosing a logging framework for an OSGi-based
> project and obviously SLF4J is a strong contender. It is nearly
> ubiquitous now and has an OSGi LogService bridge, as well as a very
> interesting implementation (Logback).
>
> However, the design of SLF4J, as it is, is somewhat OSGi unfriendly:
> we have the API bundle depending on its implementation -- and the
> opposite. This cyclic dependency is the consequence of trying to make
> it extremely easy in regular Java environments to plug a SLF4J
> implementation to the LoggerFactory, simply by "dropping a jar" in the
> runtime classpath. I don't know if the following points have been
> already discussed, and I could not find anything in the archives.
>
> I understand this solution is inherited from Log4J, and that it was
> itself a solution to the classloading problems in JCL. Dynamic binding
> and classloader hacks are clearly problematic in some setups, and
> there is no "one size fits all", because Java allows many styles and
> SLF4J, as a universal logging facade, should definitely work best
> everywhere possible.
>
> I believe SLF4J could become more universal/ubiquitous if the static
> binding approach was ad-hoc and not part of the "API side":
> OSGi/Guice/Spring folks like me could then use
> ILoggerFactory/IMarkerFactory as service specifications and use the
> more natural "dynamic binding" provided in their framework. For
> instance, component frameworks for OSGi providing DI could easily
> inject a logger by component instance (in the spirit of [1]). In OSGi
> particularly, the best practices are that an "active" service is
> provided only when the bundle is active but  stateful singletons like
> LoggerFactory don't follow these rules.
>
> The FAQ entry "Is it possible to retrieve loggers without going
> through the static methods in LoggerFactory?"[2] partly addresses
> this: yes it is already possible to ignore LoggerFactory and static
> binding. Unfortunately this is still not fully OSGi-friendly (and I
> think it applies  to any module system):
> * the current SLF4J bundle imports the package org.slf4j.impl with a
> mandatory resolution. It means there *must* be an implementation
> providing that package, and that the package *must* be exported. Best
> practices recommend making implementation packages private and thus
> non-usable by external bundles at all, even for reflection.
> * if we were to specify the resolution of org.slf4j.impl as optional,
> then any piece of code using LoggerFactory directly will default to a
> no-op logger with a message on stderr. This doesn't look like a big
> problem, but ideally in an OSGi context I would not want to provide
> that class at all and someone trying to use LoggerFactory.getLogger()
> would simply not get their component to build. Only people using
> static binding should have the class in their build classpath.
>
> I think there is not much to do to address these issues: it should be
> enough to separate binding logic (e.g LoggerFactory / MarkerFactory
> and the .spi package) into another JAR. For legacy reasons, so that
> OSGi projects already using SLF4J's static binding are not broken, and
> because split packages are generally unsupported in OSGi,
> LoggerFactory and MarkerFactory should move to another package like
> org.slf4j.staticfactories (or whatever). If they move to another
> package, there should still be LoggerFactory and MarkerFactory classes
> that redirect to the "new" ones for compatibility reasons (though
> deprecated and scheduled for removal at the next backwards
> compatibility break).
>
> The new modules available would be:
> * slf4j-api: purely API, no wiring, no state, no singletons. Default
> implementations could still be packaged here.
> * slf4j-staticbindings: providing the LoggerFactory / MarkerFactory
> classes in a new package. Only this JAR should reference
> org.slf4j.impl.
> * slf4j-compat: providing bridge between
> org.slf4j.{Logger,Marker}Factory and
> org.slf4j.staticfactories.{Logger,Marker}Factory.
> * all the existing slf4j implementations could provide both bridging
> to OSGi and through static factories.
>
> To sum up: for non-OSGi users we could keep backwards compatible for
> code, but there would be two new JARs on the classpath. It is also
> possible to merge them in a all-in-one JAR as of now. OSGi users could
> benefit from having multiple concurrent SLF4J  implementations, or
> even multiple SLF4J API versions.
>
> I'm not really sure how this proposal is going to be received (because
> this is obviously a central design choice in SLF4J). I truly think
> this is best for SLF4J to let users pick how they want to do their
> binding: it is a facade after all, it should be as abstract as
> possible. It will also make SLF4J more durable, because these
> questions will also happen when Jigsaw comes with Java 9: it is imo
> better to prepare early to avoid forks/fragmentation. My proposal will
> not break source compatibility but will make all the calls to
> LoggerFactory.getLogger() deprecated. The migrator tool could replace
> those easily, and it would still be possible to provide a compat jar.
> The cost of the indirection at class loading, especially compared to
> the classpath scanning of static binding, is negligible. The real
> problematic consequence would be for people not adding the new JARs to
> their classpath... This could be justification enough to bump the
> version to 2.0.0, to so that people know the scope of the JARs have
> been redefined (e.g, the API is backwards-compatible but the JARs are
> not).
>
> Please let me know if you think the proposal makes sense or not :), I
> would be willing to provide the necessary patches / updates to the
> FAQ.
>
> Cheers,
>
> Simon
>
>
> [1] http://www.tzavellas.com/techblog/2007/03/31/implementing-seam-style-logger-injection-with-spring/
> [2] http://www.slf4j.org/faq.html#noLoggerFactory
>


Matthew Bishop, Senior Architect
Phone: 604.408.8078 ext. 101
Email: Matthew.Bishop at elasticpath.com

Elastic Path Software, Inc.
Web: www.elasticpath.com
Blog: www.getelastic.com
Community: grep.elasticpath.com
Careers: www.elasticpath.com/jobs

Confidentiality Notice: This message is intended only for the use of the designated addressee(s), and may contain information that is privileged, confidential and exempt from disclosure. Any unauthorized viewing, disclosure, copying, distribution or use of information contained in this e-mail is prohibited and may be unlawful. If you received this e-mail in error, please reply to the sender immediately to inform us you are not the intended recipient and delete the email from your computer system. Thank you.

_______________________________________________
> slf4j-dev mailing list
> slf4j-dev at qos.ch
> http://mailman.qos.ch/mailman/listinfo/slf4j-dev
>



More information about the slf4j-dev mailing list