sbt-assembly: Logback does not work with über-JAR
Asked Answered
P

1

6

If I run the application within IntelliJ, logging works fine, but if I run the über-JAR, I get the following error:

LF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.

I use the following configuration to build my über-JAR with sbt-assembly:

lazy val app = (project in file("."))
  .settings(
    assembly / mainClass := Some("com.example.app.Main"),
    assembly / assemblyJarName := "gcm.jar",
    assembly / assemblyMergeStrategy := {
      case PathList("META-INF", xs@_*) => MergeStrategy.discard
      case PathList("reference.conf") => MergeStrategy.concat
      case x => MergeStrategy.first
    }
  )

The dependencies for Logback and scala-logging would be:

ThisBuild / libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.4.0"
ThisBuild / libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5"

The logback.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>

<configuration>
    <import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
    <import class="ch.qos.logback.core.ConsoleAppender"/>
    <import class="ch.qos.logback.core.FileAppender"/>

    <appender name="STDOUT" class="ConsoleAppender">
        <encoder class="PatternLayoutEncoder">
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="FileAppender">
        <file>gcm.log</file>
        <append>true</append>
        <immediateFlush>true</immediateFlush>
        <encoder class="PatternLayoutEncoder">
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

..

Pythoness answered 15/9, 2022 at 8:20 Comment(5)
you might need to check what is bundled in the actual jar, but I would suspect this might be a dependency conflictBatista
Is there a way to find out if that is the case - and if - what causes the conflict?Pythoness
if there is any conflicts you would see warning during compilation, other way to dig in into this used to be github.com/sbt/sbt-dependency-graph plugin, not sure but its still in use as far as I knowBatista
I have the same issue, @hannes have you found a solution?Mammon
Unfortunately, no.Pythoness
G
8

This happens because Service Providers (defined in META-INF) are discarded by your merge strategy. I had the same issue when migrating from logback 1.2.x to 1.4.x.

One option I found in sbt-assembly doc is to replace your META-INF case with:

case PathList("META-INF", xs@_*) =>
  (xs map {_.toLowerCase}) match {
    case "services" :: xs =>
      MergeStrategy.filterDistinctLines
    case _ => MergeStrategy.discard
  }

Is there a way to find out if that is the case - and if - what causes the conflict?

Running in debug mode ./sbt assembly --debug might help identifying which files are discarded:

...
[debug] Merging 'META-INF/services/ch.qos.logback.classic.spi.Configurator' with strategy 'discard'
[debug] Merging 'META-INF/services/jakarta.servlet.ServletContainerInitializer' with strategy 'discard'
[debug] Merging 'META-INF/services/org.slf4j.spi.SLF4JServiceProvider' with strategy 'discard'
...
Galvan answered 26/10, 2022 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.