javarosa icon indicating copy to clipboard operation
javarosa copied to clipboard

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

Open joeflack4 opened this issue 7 years ago • 5 comments

Software versions

JavaRosa v2.11.1, Java v1.8, OSX High Sierra

Problem description

I am receiving the following message when trying to utilize org.javarosa.core.services.PropertyManager:

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.

Steps to reproduce the problem

Try: I'm utilizing like this: org.javarosa.core.services.PropertyManager.setPropertyManager(new StubPropertyManager());`.

Expected behavior

No such error message / dependency on sl4j when using JavaRosa as a dependency. Should not receive this error message.

Other information

I checked out the error code help online: https://www.slf4j.org/codes.html#StaticLoggerBinder

It said:

Note that embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose.

However it's strange that JavaRosa's gradle says this: compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' And pom.xml for maven says:

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>

So I'm not sure why I was getting that error message. I've since silenced it on my end by installing a dependency as instructed by sl4j, but ideally I wouldn't want to do that.

joeflack4 avatar Oct 18 '18 20:10 joeflack4

Hi, @joeflack4!

I believe everything you're reporting is actually what we should expect.

JR depends on SLF4J for logging but it doesn't include any specific implementation of SLF4J. This lets anyone wanting to use JR to use any library they want. For example, Briefcase uses Logback.

The slf4j-api dependency you see is the way JR expresses that the code uses SLF4J logging and needs anyone using it to provide an actual implementation of the slf4j api.

Another example of this is the testing dependency you can see in the gradle build file: testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'

This is the implementation we provide for testing, which doesn't get included into the production JAR file.

ggalmazor avatar Oct 19 '18 08:10 ggalmazor

Thanks for the explanation.

I'm still pretty noob at Java.

I'm wondering why I saw any error messages about SLF4J when using JavaRosa as a library in my tool at all. It looks like JavaRosa is using slf4j-api 1.7.25, however the SLF4J docs say that:

Failed to load class org.slf4j.impl.StaticLoggerBinder This warning message is reported when the org.slf4j.impl.StaticLoggerBinder class could not be loaded into memory. This happens when no appropriate SLF4J binding could be found on the class path. Placing one (and only one) of slf4j-nop.jar slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar or logback-classic.jar on the class path should solve the problem.

SINCE 1.6.0 As of SLF4J version 1.6, in the absence of a binding, SLF4J will default to a no-operation (NOP) logger implementation.

If you are responsible for packaging an application and do not care about logging, then placing slf4j-nop.jar on the class path of your application will get rid of this warning message. Note that embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose.

Despite what's bolded there, I still continued to see messages until I included the slf4j no-op dependency in my package. I wonder why...

joeflack4 avatar Oct 24 '18 00:10 joeflack4

I still continued to see messages until I included the slf4j no-op dependency in my package. I wonder why...

That's expected too: the api is not an implementation of SLF4J. It contains only empty interfaces you can use in your code, but in runtime, some library has to implement them.

The api dependency will complain until you provide an actual implementation of the api. the no-op dependency implements the api by not doing anything. Briefcase uses Logback for that.

ggalmazor avatar Oct 25 '18 07:10 ggalmazor

Ahh, Ok. The bolded part, I think I misread. What I thought it was saying was that if you use slf4j-api but don't actually import another implementation, then slf4j-api would actually implement 'no-op' on its own.

Thanks for helping me understand this!

joeflack4 avatar Oct 26 '18 13:10 joeflack4

Thank you so much for this! It helped me out.

AdrianAcostaPR avatar Jun 26 '21 19:06 AdrianAcostaPR