[slf4j-user] Fail Silently on NOP implementation

Phillip Lord phillip.lord at russet.org.uk
Thu Apr 28 21:53:36 UTC 2016


Joachim Durchholz <jo at durchholz.org> writes:

> Am 28.04.2016 um 22:15 schrieb Phillip Lord:
>>
>> This is not true. My library has around 70 dependencies, some of which I
>> have never heard of. As the recent debacle with left-pad and NPM has
>> shown, very few people are consciously aware of all their dependencies.
>
> I agree with your sentiment that one shouldn't need to bother that much about
> indirect dependencies; I think logging has become because it's a cross-cutting
> concern, just like the availability of stdout and whether it's a tty or a
> pipe.

Logging is, I agree, a difficult one, and what to do during bootstrap of
the logger is particularly nasty.


> Now if you're writing a library you should never bother with logging
> configuration. Maybe make sure it doesn't clutter your unit-testing
> output, but that's more cosmetic than anything. If, on the other hand,
> you're writing an application, you definitely need to configure
> logging.

As I have said, this distinction is artificial.


> The good news is that the NOP logger message you are seeing is just a
> misconfiguration.

No, the logger message is coming directly from slf4j-api. The code
is here, in LoggerFactory.java.

      if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
        INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
        Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
        Util.report("Defaulting to no-operation (NOP) logger implementation");
        Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
      }



> many libraries are misguided in that they declare a dependency on a
> logging backend, and you need to exclude that

I think including an explict dependency on the slf4j-nop backend is the
correct thing to do. Otherwise, slf4j-api prints an error message.


>> Yes, although these do not equate to the artifacts. slf4j-api is
>> actually the API and the NOP logger.
>
> Last time I looked these were different libraries.

I'm sorry to contradict you again, but I'm afraid you are wrong. The
NOPLogger is in org.slf4j.helpers.NOPLogger, and it's packaged as part
of slf4j-api. It would have to be, else how could slf4j-api fallback to
it?

slf4j-nop simply provides the StaticLoggerBinder which, erm, binds the
logger statically. Having done so, slf4j-api finds
org.slf4j.helpers.NOPLoggerFactory through reflection at runtime, rather
than at compile time, and in the process supresses the warning.


> I dimly recall that slf4j-api didn't even pull in any logger as a
> dependency

It doesn't. It just includes the NOPLogger directly.

>> If not, I will just include slf4j-nop directly and leave it at that.
>
> From the keywords I have seen, you're getting messages because you have more
> than one logging backend in your classpath, slf4j-nop and something else.
> Including slf4j-nop will not change anything about that.

I'm getting error messages because there is no binding. I want to stop
this. The simple way to do this with slf4j is to include slf4j-nop.

The only other solutions that I can see are:

1) Ask the slf4j developers to not print an error message.

2) Replacing System.err with a PrintStream that looks for the error
   messages from slf4j and filters them.

3) Creating a slf4j binding which looks for other bindings in the same
   way as StaticLoggerBinder, automatically defers to one if it finds it
   (and without complaining to System.err), falls back to nop otherwise.

4) Forking slf4j and removing the error message there.

This is in approximately decreasing order of sanity.

Phil


More information about the slf4j-user mailing list