Logging to file in Scala/akka: ClassNotFoundExcept

2019-04-06 23:09发布

问题:

I have searched quite a bit but could not find a working solution. Could someone please help me?

akka {
     event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
     loggers = ["akka.event.slf4j.Slf4jLogger"]
     loglevel = "DEBUG"
     logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
     stdout-loglevel = "WARNING"
     actor {
       debug {
         receive = on
         lifecycle = off
       }
     }
}

and I have added the following to build.sbt in the hope that one of them solves the issue:

libraryDependencies ++= Seq (
  "com.typesafe.akka" %% "akka-actor" % "2.4.1",   // akka actors
  "ch.qos.logback" % "logback-classic" % "1.1.3",  //logback, in order to log to file
  "com.typesafe.scala-logging" % "scala-logging-slf4j_2.11" % "2.1.2",
  "com.typesafe.akka" % "akka-slf4j_2.11" % "2.4.1",   // needed for logback to work
  // and my other dependencies
)

and I have tried with different suggestions I found for logback.xml, the last of which is:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/filename.log</file>
        <encoder>
            <pattern>%date %level %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <maxIndex>10</maxIndex>
            <FileNamePattern>logs/filename.log.%i.gz</FileNamePattern>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>20MB</maxFileSize>
        </triggeringPolicy>
    </appender>
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

EDIT: My complete dependencies are as follows (ps: I currently have both lift and salat for de/serialization, but that's a different story):

libraryDependencies ++= Seq (
  "org.scala-lang" % "scalap" % scalaVersion.value, 
  "com.typesafe.akka" %% "akka-actor" % "2.4.1",   
  "ch.qos.logback" % "logback-classic" % "1.1.3",  
  "com.typesafe.scala-logging" % "scala-logging-slf4j_2.11" % "2.1.2",
  "com.typesafe.akka" %% "akka-slf4j" % "2.4.1",  
  "com.github.sstone" %% "amqp-client" % "1.5", 
  "net.liftweb" %% "lift-json" % "2.6.2",
  "net.liftweb" %% "lift-json-ext" % "2.6.2",    
  "org.scalatest" %% "scalatest" % "2.2.4" % "test",
  "com.novus" %% "salat" % "1.9.9"
)

回答1:

So you use "com.novus" %% "salat" % "1.9.9" which depends on salat-util % 1.9.9, which depends on org.slf4j % slf4j-api % 1.7.2. Akka "com.typesafe.akka" %% "akka-slf4j" % "2.4.1" depends on 1.7.12. Make sure that you need the whole salat package. Probably you could find a way of using only part of it, or configure logging in different way, or wait for update from Salat developers.



回答2:

@Mahdi: Not sure if you were able to solve your problem, but I faced the same problem and figured out that the correct version of "com.typesafe.akka" %% "akka-slf4j" % "2.4.0", was not included in my build.sbt.



回答3:

The best way to solve these kind of problems is always see the dependency tree and figure out whats going on there, (its very important be it maven or sbt)

See how many slf4j dependencies you have. (I can see conflicting dependencies slf4j-api:1.6.0, slf4j-api:1.7.2, slf4j-api:1.7.12)

sbt dependencyTree

[info]   +-com.novus:salat_2.11:1.9.9 [S]
[info]   | +-com.novus:salat-core_2.11:1.9.9 [S]
[info]   | | +-com.novus:salat-util_2.11:1.9.9 [S]
[info]   | | | +-org.scala-lang:scalap:2.11.5
[info]   | | | | +-org.scala-lang:scala-compiler:2.11.5 [S]
[info]   | | | |   +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.1 (evicted by: 1.0.3)
[info]   | | | |   +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.3 [S]
[info]   | | | |   +-org.scala-lang.modules:scala-xml_2.11:1.0.1 (evicted by: 1.0.3)
[info]   | | | |   +-org.scala-lang.modules:scala-xml_2.11:1.0.3 [S]
[info]   | | | |   +-org.scala-lang:scala-reflect:2.11.5 [S]
[info]   | | | |   
[info]   | | | +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | | | +-org.slf4j:slf4j-api:1.7.12
[info]   | | | +-org.slf4j:slf4j-api:1.7.2 (evicted by: 1.7.12)

[info]   +-ch.qos.logback:logback-classic:1.1.3
[info]   | +-ch.qos.logback:logback-core:1.1.3
[info]   | +-org.slf4j:slf4j-api:1.7.12
[info]   | +-org.slf4j:slf4j-api:1.7.7 (evicted by: 1.7.12)

[info]   | | +-org.mongodb:casbah-core_2.11:2.7.1 [S]
[info]   | |   +-com.github.nscala-time:nscala-time_2.11:1.0.0 [S]
[info]   | |   | +-joda-time:joda-time:2.3
[info]   | |   | +-org.joda:joda-convert:1.2
[info]   | |   | 
[info]   | |   +-org.mongodb:casbah-commons_2.11:2.7.1 [S]
[info]   | |   | +-com.github.nscala-time:nscala-time_2.11:1.0.0 [S]
[info]   | |   | | +-joda-time:joda-time:2.3
[info]   | |   | | +-org.joda:joda-convert:1.2
[info]   | |   | | 
[info]   | |   | +-org.mongodb:mongo-java-driver:2.12.1
[info]   | |   | +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | |   | +-org.slf4j:slf4j-api:1.7.12
[info]   | |   | 
[info]   | |   +-org.mongodb:casbah-query_2.11:2.7.1 [S]
[info]   | |   | +-com.github.nscala-time:nscala-time_2.11:1.0.0 [S]
[info]   | |   | | +-joda-time:joda-time:2.3
[info]   | |   | | +-org.joda:joda-convert:1.2
[info]   | |   | | 
[info]   | |   | +-org.mongodb:casbah-commons_2.11:2.7.1 [S]
[info]   | |   | | +-com.github.nscala-time:nscala-time_2.11:1.0.0 [S]
[info]   | |   | | | +-joda-time:joda-time:2.3
[info]   | |   | | | +-org.joda:joda-convert:1.2
[info]   | |   | | | 
[info]   | |   | | +-org.mongodb:mongo-java-driver:2.12.1
[info]   | |   | | +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | |   | | +-org.slf4j:slf4j-api:1.7.12
[info]   | |   | | 
[info]   | |   | +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | |   | +-org.slf4j:slf4j-api:1.7.12
[info]   | |   | 
[info]   | |   +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | |   +-org.slf4j:slf4j-api:1.7.12

[info]   | +-com.novus:salat-util_2.11:1.9.9 [S]
[info]   |   +-org.scala-lang:scalap:2.11.5
[info]   |   | +-org.scala-lang:scala-compiler:2.11.5 [S]
[info]   |   |   +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.1 (evicted by: 1.0.3)
[info]   |   |   +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.3 [S]
[info]   |   |   +-org.scala-lang.modules:scala-xml_2.11:1.0.1 (evicted by: 1.0.3)
[info]   |   |   +-org.scala-lang.modules:scala-xml_2.11:1.0.3 [S]
[info]   |   |   +-org.scala-lang:scala-reflect:2.11.5 [S]
[info]   |   |   
[info]   |   +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   |   +-org.slf4j:slf4j-api:1.7.12
[info]   |   +-org.slf4j:slf4j-api:1.7.2 (evicted by: 1.7.12)

[info]   +-com.typesafe.scala-logging:scala-logging-slf4j_2.11:2.1.2 [S]
[info]   | +-com.typesafe.scala-logging:scala-logging-api_2.11:2.1.2 [S]
[info]   | +-org.scala-lang:scala-reflect:2.11.5 [S]
[info]   | +-org.slf4j:slf4j-api:1.7.12
[info]   | +-org.slf4j:slf4j-api:1.7.7 (evicted by: 1.7.12)

[info]   +-net.liftweb:lift-json-ext_2.11:2.6.2 [S]
[info]   | +-commons-codec:commons-codec:1.6
[info]   | +-joda-time:joda-time:2.1 (evicted by: 2.3)
[info]   | +-joda-time:joda-time:2.3
[info]   | +-net.liftweb:lift-common_2.11:2.6.2 [S]
[info]   | | +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.1 (evicted by: 1.0.3)
[info]   | | +-org.scala-lang.modules:scala-parser-combinators_2.11:1.0.3 [S]
[info]   | | +-org.scala-lang.modules:scala-xml_2.11:1.0.1 (evicted by: 1.0.3)
[info]   | | +-org.scala-lang.modules:scala-xml_2.11:1.0.3 [S]
[info]   | | +-org.slf4j:slf4j-api:1.6.0 (evicted by: 1.7.12)
[info]   | | +-org.slf4j:slf4j-api:1.7.12
[info]   | | +-org.slf4j:slf4j-api:1.7.2 (evicted by: 1.7.12)

And to know what version is used,

$ sbt dependencyList
[info] org.slf4j:slf4j-api:1.7.12

That way you can control which version you want and which you want to exclude,

eg. to exclude the slf4j-api version that salat uses

"com.novus" %% "salat" % "1.9.9" exclude("org.slf4j","slf4j-api")

Note

add addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.8.2") to project/plugins.sbt to use sbt dependencyTree.

https://github.com/jrudolph/sbt-dependency-graph#usage-instructions