Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SLF4J Custom Binding Not Working

We spent a lot of time developing our own custom logging system (right or wrong, thats what the higher-ups decided on!) and I have been asked to write a custom SLF4J binding (API implementation) so that many of our SLF4J-utilizing components (such as Apache Camel) will start logging to our new homegrown system.

I have followed the instructions on SLF4J's site to a "T", creating:

  • A StaticLoggerBinder that SLF4J uses at runtime to bind to Loggers and LoggerFactory classes
  • A logger adaptor that will be used to "forward" org.slf4j.Logger calls on to
  • A logger factory (used by the static logger binder)

Everything compiles great. I jar it up and add it to the lib directory of a test project, along with slf4j-api-1.6.2.jar (the version they want me to use). I added both JARs to the build path in Eclipse.

I create a new Run Configuration for the test project, and under the Run Configuration's Classpath tabbed pane I see it has User Entries >> TestBinding >> Slf4jBinding.jar and slf4j-api-1.6.2.jar.

So, it seems like both JARs are inside the Run Configuration's classpath.

Upon running a driver inside the project that looks like this:

public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(TestDriver.class);
    logger.error("Test");
}

I get the following runtime errors:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Going to that referenced site, it seems that SLF4J cannot find my StaticLoggerBinder on the classpath, which is inside the Slf4jBinding.jar, although not at the root level of the JAR.

I looked at SLF4J's LoggerFactory.java source file and found the code that throws this kind of error:

private final static void bind() {
    try {
        // the next line does the binding
        StaticLoggerBinder.getSingleton();
        INITIALIZATION_STATE = SUCCESSFUL_INITILIZATION;
        emitSubstituteLoggerWarning();
    } catch (NoClassDefFoundError ncde) {
        String msg = ncde.getMessage();
        if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
            INITIALIZATION_STATE = NOP_FALLBACK_INITILIZATION;
            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.");
        } // ...

Clearly, the call at the top of the try block (StaticLoggerBinder.getSingleton()) is throwing the NoClassDefFoundError. I just don't understand why.

I elected not to paste my code here because I think this is just a classpath issue. Whether or not my code correctly adheres to SLF4J's binding policies remains unknown until I can get passed this issue.

Is there an additional step I need to take inside Eclipse to configure the classpath? Could my Slf4jBinding.jar need StaticLoggerBinder inside its root for some reason? I am out of ideas here. Thanks in advance!

like image 272
IAmYourFaja Avatar asked Oct 21 '25 04:10

IAmYourFaja


2 Answers

Your jar needs a custom implementation of org.slf4j.impl.StaticLoggerBinder and that implementation's fully qualified class name must be exactly org.slf4j.impl.StaticLoggerBinder. The static binding works having the SLF4J API compiled against a stub version of org.slf4j.impl.StaticLoggerBinder and then at runtime a classloader will load a real version from an SLF4J binding . Each binding of SLF4J has a different version of a the class org.slf4j.impl.StaticLoggerBinder suitable for that particular binding.

like image 126
Dev Avatar answered Oct 23 '25 20:10

Dev


Instead of starting completely from scratch then just adapt e.g. slf4j-simple.jar to your needs. All the binding code is there, you just need to adapt the code doing the actual logging.

like image 39
Thorbjørn Ravn Andersen Avatar answered Oct 23 '25 20:10

Thorbjørn Ravn Andersen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!