我遇到了akka.ConfigurationException: Akka JAR version [2.1.0] does not match the provided config version [2.2.3]
。我的猜测是,不知何故,$SCALA_HOME/lib/akka-actors.jar
与SBT管理的Akka JAR一起进入类路径。
我创建了一个简单的独立SBT项目来演示该问题(见下文)。我的$ SCALA_HOME指向Scala 2.10.3。在Build.scala中,我明确地将scalaHome
设置为$SCALA_HOME
project/Build.scala
import sbt._
import sbt.Keys._
object ApplicationBuild extends Build {
val appName = "akka-version-problem"
val appVersion = "0.1-SNAPSHOT"
val getJars = TaskKey[Unit]("get-jars")
val getJarsTask = getJars <<= (target, fullClasspath in Compile) map { (target, cp) =>
println(cp map { _.data } filter { _.getAbsolutePath.contains("lib") } mkString "\n")
println(cp map { _.data } filter { _.getAbsolutePath.contains("akka") } mkString "\n")
}
lazy val root = Project("root", file(".")).settings(
scalaVersion := "2.10.3",
scalaHome := Some(file(System.getenv("SCALA_HOME"))),
autoScalaLibrary := false,
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.2.3"
),
getJarsTask
)
}
src/main/scala/com/example/Main.scala
package com.example
import akka.actor.ActorSystem
object Main extends App {
val system = ActorSystem("AkkaDemoSystem")
system.shutdown()
}
当我运行sbt get-jars
时,我在输出中看不到$SCALA_HOME/lib/akka-actors.jar
当我运行sbt run
时,我得到:
[error] (run-main) 44c2d48a-8899-43f9-804b-55cbf739b08bakka.ConfigurationException: Akka JAR version [2.1.0] does not match the provided config version [2.2.3]
44c2d48a-8899-43f9-804b-55cbf739b08bakka.ConfigurationException: Akka JAR version [2.1.0] does not match the provided config version [2.2.3]
at akka.actor.ActorSystem$Settings.<init>(ActorSystem.scala:172)
at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:465)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:111)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:93)
at com.example.Main$delayedInit$body.apply(Main.scala:6)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
at scala.App$class.main(App.scala:71)
at com.example.Main$.main(Main.scala:5)
at com.example.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
我错过了一些明显的东西吗?还有其他人遇到过这个吗?
答案 0 :(得分:3)
这里的问题是akka-actors.jar是scala发行版的 part 。默认情况下,Sbt包含类路径中的所有这些jar。所以,你最终使用scala发行版中的Akka版本和直接依赖的版本。
不仅如此,你还包括scala-actors,scala-reflect等。如果这是你想要的,那很好。
如果您想阻止自己使用比您想要的更多的罐子,您应该直接创建scalaInstance
。有关构造方法,请参阅http://www.scala-sbt.org/release/api/index.html#sbt.ScalaInstance $(您可以看到其中一个使用scalaHome)。
我建议做类似的事情(注意:sbt 0.13代码):
scalaInstance := {
val homeDir = file("/path/to/scala-home")
val jars = (homeDir ** ".jar").get
val notAkka = jars filterNot (_ contains "akka")
val scalaLib = ScalaInstance.scalaJar(homeDir, "scala-library.jar")
val compilerLib = ScalaInstance.scalaJar(homeDir, "scala-compiler.jar")
ScalaInstance(scalaLib, compilerLib, notAkka:_*)(state.classLoaderCache.apply _)
}
这会激发您弃用的警告。这是因为我们假设如果您正在使用scalaHome,那么想要来自scala的所有默认模块。由于情况并非如此,您可以忽略它。
正如Viktor所说,我建议只使用sbt的Scala解析机制。默认情况下,如果您执行此操作,则默认情况下会执行类加载器的缓存,和它只会下载一次工件。实际情况是,sbt必须下载scala版本才能编译你的构建,然后才知道你已经为项目配置了scalaHome(因为你使用scala本身指定了这个)。
希望有所帮助!