Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built JAR Errors - SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" #372

Closed
kuro337 opened this issue Nov 25, 2023 · 3 comments

Comments

@kuro337
Copy link

kuro337 commented Nov 25, 2023

Hey!

I have been struggling with this for a week now - and trying so many different things none seem to work.

I am basically trying to use KotlinLogger with a Logback.xml file for a structure - and need to figure out a way to get it to work.

My understanding is using Logback-classic is required to use a structure with KotlinLogger along with this works

However whenever I build the ShadowJar - I see these 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.

But when I run the app through the IDE - the logging appears fine

25-Nov-23 01:17:29.388 [main] INFO  eventstream.beam.logger.BeamLogger - main - Starting Kafka Reader App
25-Nov-23 01:17:30.800 [main] INFO  eventstream.beam.logger.BeamLogger - main - Read from Kafka Topic my-topic Success - checking Events
25-Nov-23 01:17:32.500 [main] INFO  o.a.k.c.consumer.ConsumerConfig - logAll - ConsumerConfig values: 

After checking lots of places and the docs - my understanding is that this is happening because logback classic requires this dependency too?

  • api("org.slf4j:slf4j-api:2.0.9")

so I have added it - and tried all variations of including these

   api("ch.qos.logback:logback-classic:1.4.11")
    api("ch.qos.logback:logback-core:1.4.11")

    api("io.github.oshai:kotlin-logging-jvm:5.1.0")
    api("org.slf4j:slf4j-api:2.0.9")

Yet i always see the same error

My entire build.gradle.kts is :

plugins {
    id("eventstream.kotlin-application-conventions")
    id("maven-publish")
    id("java-library")
    id("com.github.johnrengelman.shadow") version "7.1.2"
    application
}

dependencies {

    configurations {
        all {
            exclude(group = "org.slf4j", module = "slf4j-simple")
        }
    }

    api("ch.qos.logback:logback-classic:1.4.11")
    api("ch.qos.logback:logback-core:1.4.11")

    api("io.github.oshai:kotlin-logging-jvm:5.1.0")
    api("org.slf4j:slf4j-api:2.0.9")

    api("org.jetbrains.kotlin:kotlin-reflect:1.9.20")

    api("org.apache.commons:commons-text")
    api("org.apache.beam:beam-sdks-java-core:2.50.0")
    api("org.apache.beam:beam-runners-direct-java:2.50.0")
    api("org.apache.beam:beam-runners-flink-1.16:2.50.0")
    api("org.apache.beam:beam-sdks-java-io-amazon-web-services2:2.51.0")
    api("org.apache.beam:beam-sdks-java-io-parquet:2.51.0")
    api("org.apache.beam:beam-sdks-java-io-kafka:2.52.0")

    api("org.apache.kafka:kafka-clients:3.6.0") // interact with kafka
    implementation("io.confluent:kafka-avro-serializer:7.5.1")
    implementation("io.confluent:kafka-schema-registry-client:7.5.1")

    implementation("org.apache.hadoop:hadoop-core:1.2.1")
    api("software.amazon.awssdk:s3:2.21.10")

    /* Test Deps */
    testImplementation("eventstream:utilities:1.0.0")

    testImplementation("org.apache.beam:beam-sdks-java-test-utils:2.51.0")
    testImplementation("junit:junit:4.13.2") // JUnit 4 for TestPipeline support
    testImplementation("org.jetbrains.kotlin:kotlin-test:1.9.20")
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
    testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.8.1")

}


/* Build ShadowJar for Flink */

tasks.shadowJar {
    transform(com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer::class.java)
    isZip64 = true
    archiveFileName.set("FlinkApp-all.jar")
    mergeServiceFiles()
    manifest {
        attributes["Main-Class"] = "eventstream.beam.FlinkAppKt"
    }
}

java {
    withJavadocJar()
    withSourcesJar()
}

application {
    mainClass.set("eventstream.beam.FlinkAppKt")
}

My logback.xml is

<configuration>
    <!-- ConsoleAppender sends logged messages to the console -->

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- Pattern layout for logging. %d is the date, %logger is the logger name, %M is the method name, %msg is the message -->
            <pattern>%d{dd-MMM-yy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %M - %msg%n</pattern>

        </encoder>
    </appender>
    <!-- Root logger configuration -->
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

I build the jar and run these commands and I see all

jar tf beam/build/libs/FlinkApp-all.jar | grep 'org/slf4j'
jar tf beam/build/libs/FlinkApp-all.jar | grep 'ch/qos/logback'
jar tf beam/build/libs/FlinkApp-all.jar | grep 'logback.xml'

Does anyone have any insight or recommendations? Would greatly appreciate it!

The Error is always

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.
Testing new log
@oshai
Copy link
Owner

oshai commented Nov 25, 2023

I think slf4j might rely on jar name to find the correct logging lib and maybe that's why it doesn't find it.

@kuro337
Copy link
Author

kuro337 commented Nov 26, 2023

Hmm I checked again and spent time doing it , I believe the classes are there in the Class Path

for example in a project just with the logging

plugins {
    id("eventstream.kotlin-application-conventions")
    application
    id("com.github.johnrengelman.shadow") version "7.1.2"
}

configurations {
    all {
        exclude(group = "org.slf4j", module = "slf4j-simple")
        exclude(group = "org.slf4j", module = "slf4j-nop")
        exclude(group = "org.slf4j", module = "slf4j-jdk14")
    }
}

dependencies {
    implementation("eventstream:beam:1.0.3")
    implementation("ch.qos.logback:logback-classic:1.4.11")
    api("io.github.oshai:kotlin-logging-jvm:5.1.0")
    api("eventstream:utilities:1.0.0")
}

application {
    mainClass.set("eventstream.app.AppKt")
}

tasks.shadowJar {
    mergeServiceFiles()
    transform(com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer::class.java)

    isZip64 = true
    archiveFileName.set("KafkaAppLibUsage-all.jar")

    manifest {
        attributes["Main-Class"] = "eventstream.app.AppKt"
    }
}

App Code

fun main() {
    /*

    Staging Application to use Functionality from Library.

     */
    try {
        // Check manually load the StaticLoggerBinder class
        Class.forName("org.slf4j.impl.StaticLoggerBinder")
        println("StaticLoggerBinder loaded successfully.")
    } catch (e: ClassNotFoundException) {
        println("Error loading StaticLoggerBinder: ${e.message}")
    }
    
    print("Logger Factory - class ")

    println("Classpath: " + System.getProperty("java.class.path"))


    val logger = KotlinLogging.logger {}


    logger.info { "Starting Kafka Reader App" }

    val pipeline = Pipeline.create(/* your pipeline options */)

    println("Testing new log")
    ....

When I build and run - always see

chinm@DESKTOP-H0OMSKL MINGW64 /d/Code/Kotlin/projects/eventstream (main)
$ java -Dlogback.debug=true -jar app/build/libs/KafkaAppLibUsage-all.jar
Error loading StaticLoggerBinder: org.slf4j.impl.StaticLoggerBinder
Logger Factory - class Classpath: app/build/libs/KafkaAppLibUsage-all.jar
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.
Testing new log
# Check Logback.xml
jar tf ../app/build/libs/KafkaAppLibUsage-all.jar | grep 'logback.xml'
# logback.xml

# Check SLF4J Service Provider Configuration
jar tf ../app/build/libs/KafkaAppLibUsage-all.jar | grep 'META-INF/services/org.slf4j.spi.SLF4JServiceProvider'
# META-INF/services/org.slf4j.spi.SLF4JServiceProvider


# Check that it points to LogbackServiceProvider
cat META-INF/services/org.slf4j.spi.SLF4JServiceProvider
# ch.qos.logback.classic.spi.LogbackServiceProvider

I see logback.xml and the Service Provider above

Also tried it without any of these - same results

configurations {
    all {
        exclude(group = "org.slf4j", module = "slf4j-simple")
        exclude(group = "org.slf4j", module = "slf4j-nop")
        exclude(group = "org.slf4j", module = "slf4j-jdk14")
    }
}

- Also tried with different versions of logback

implementation("ch.qos.logback:logback-classic:1.4.11")

implementation("ch.qos.logback:logback-classic:1.4.9")

implementation("ch.qos.logback:logback-classic:1.4.6")

@oshai
Copy link
Owner

oshai commented Nov 26, 2023

I believe the classes are there in the Class Path

I think the problem is not that the classes are not in the classpath, but the original jars must be in the classpath (that's how slf4j decide which logging framework to use).

@oshai oshai closed this as completed Apr 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants