[slf4j-user] Fail Silently on NOP implementation
Ceki Gulcu
ceki at qos.ch
Fri Apr 29 10:26:29 UTC 2016
My comments are inline.
On 4/29/2016 0:58, Robert Elliot wrote:
> >
> > As I have said, this distinction is artificial.
>
> It isn’t, in my opinion. The distinction between a process and a
> library is fundamental. A process must, of its nature, have resolved
> all its dependencies to concrete implementations. A library should, of
> its nature, couple as lightly as possible to implementations of APIs
> it depends on in order to free the hands of the process depending on
> that library.
>
> It is of course easy to create an artefact that can be both be run as
> a process and depended on as a library, but that conflates two
> separate concerns and doing so is inherently problematic.
Robert, I agree with you. The distinction of library vs. application
is essential to the problem at hand. However, it seems that this view
is not shared by all. The core question is whether SLF4J needs to
accomodate this different point of view. At this stage, my inclination
is to recognize that some developers conflate librarries and
applications but otherwise to politely ignore their pov.
> Unless your dependency mechanism allows for defining different
> dependencies for an artefact when it is running as a process or acting
> as a library for a different process (and Maven’s transitive
> dependency system, which has become the de facto standard, does not)
> there is no perfect solution for this. In the case of SLF4J there are
> the following options:
>
> 1) Add a dependency on slf4j-nop to the artefact. This will badly
> affect anyone who depends on your artefact as a library to their
> process, they will find themselves with multiple SLF4J implementations
> on the classpath, which will at a minimum print an error and 50% of
> the time will ‘win’ and remove all their logging output and require
> them to work out how to exclude slf4j-nop to get it back. As Maven in
> XML has no (non-hacky) means of global dependency exclusion this may
> be a significant headache for them.
>
> 2) Silently do a nop in SLF4J if no implementation is present. This
> will give no hint to the unaware user as to why they are getting no
> logging feedback from their process and what they should do to fix it.
>
> 3) Exit the process aggressively (via an exception) if no logging
> implementation is present
>
> 4) Separate the artefact into two artefacts - one a library containing
> 99% of the logic and depending on slf4j-api alone, and the other a
> main method that depends on the library and slf4j-nop, and document
> which the user should use depending on whether they want a library or
> a process.
>
> 5) Print some description as to how to provide an SLF4J implementation
> and otherwise allow the process to carry on
>
> There are other approaches, and possibly better ones, to logging than
> SLF4J - I’m far from convinced that the static procedural approach
> where the implementation is looked up and used without the caller
> having control is a good one. But we are where we are, and libraries
> routinely statically depend on slf4j, so 5) seems to me the least bad.
SLF4J's approach of binding with an implementation by directly
invoking the org.slf4j.impl.StaticLoggerBinder.getSingleton() method
from within LoggerFactory is primitive and very unsophisticated. Other
approaches to this problem, e.g. OSGi, address many of the
shortcomings of the direct invocation approach. However, OSGi is very
hard to master and only a small minority of developers understand
it. In contrast, the SLF4J approach can be understood by most
programmers on their first day of programming in Java.
SLF4J's static binding approach is a direct reaction to the dynamic
binding approach (via classloader inspection) as adopted by Jakarta
Common Logging. The classloader approach is more convenient in many
cases but may become extremely complicated to debug when things go
wrong, see [1].
When SLF4J came out in 2004, JCL had 100% share of the "logging
abstraction" market. Things have changed considerably since. Rightly
or wrongly, I attribute much of SLF4J's success to static binding
although other factors surely played a role as well.
Jigsaw (new in Java 9) purportedly provides a solution to the jar hell
problem. I wonder how SLF4J could be modified to cater for Jigsaw
modules.
--
Ceki
[1] http://articles.qos.ch/classloader.html
More information about the slf4j-user
mailing list