我试图在我为我的SBT构建编写的任务中运行一个相当简单的HTTP请求,并且看到SBT似乎没有为此提供帮助,所以我决定使用喷雾客户机来完成这个任务。
在一个project/dependencies.sbt文件中,我放置了以下内容:
resolvers += "spray.io repo" at "http://repo.spray.io/"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.2.3",
"io.spray" % "spray-client" % "1.2.0")我的任务是:
def uploadSite(version: String, siteArchive: File, log: Logger): HttpResponse = {
def request: HttpRequest = Post(siteUploadUrl,
MultipartFormData(Map(
// abridged
))
implicit val system = ActorSystem() // <-- Exception HERE!
try {
import system.dispatcher
val future: Future[HttpResponse] = pipelining.sendReceive(request)
Await.result(future, 1 minute)
}
finally system.shutdown()
}除以下异常外,当我运行该任务时,该任务将失败:
com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'akka'
at com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:115)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:138)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:150)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:155)
at com.typesafe.config.impl.SimpleConfig.getString(SimpleConfig.java:197)
at akka.actor.ActorSystem$Settings.<init>(ActorSystem.scala:136)
at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:470)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:111)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:93)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:82)
at MyIO$.uploadSite(MyIO.scala:65)我的基本分析是,可以在reference.conf中找到的akka-actor_2.10-2.2.3.jar文件不被读取,因为某些原因使我无法理解,而且可能与SBT如何管理其类路径来运行构建有关。
一些精确性:我使用的是SBT0.13.0(因此使用Scala2.10表示构建代码),并且我检查了前面提到的actor确实包含一个reference.conf文件,这与预期的一样。当查看可能与构建执行类路径(reload plugins,然后在sbt中的show runtime:fullClasspath )相关的内容时,jar会出现在列表中。
我在谷歌搜索任何相关内容时也失败了,因为我无法传达问题在于从SBT构建中运行akka。
最后,我真的不知道“akka”配置键怎么会丢失。有人能帮忙吗?
发布于 2013-12-09 14:31:07
akka真正令人烦恼的是,您需要更新线程本地上下文类加载器以进行泛型设置,而许多工具(如sbt)则不更新,因为它们不知道在哪个线程上运行或需要哪个类加载器。
下面是活化剂的一个例子构建:
val cl = ??? // Some mechanism of getting Akka's classpath with your classes too
val old = Thread.currentThread.getContextClassLoader
Thread.currentThread.setContextClassLoader(cl)
try doSomethingWithAkka()
finally Thread.currentThread.setContextClassLoader(old)编辑(由OP)使这比在注释中更可见:
Akka (从2.0开始)选择它在ActorSystem中使用的类加载器(当它不是作为参数传递时),方法是从以下内容中选择第一个可用的(和非空的):
Thread.currentThread.getContextClassLoadergetClassLoader。ActorSystem.getClass.getClassLoader所以,这就是为什么上面的变异上下文类加载器的解决方案是有效的。
至于实际使用的类加载器,我得到了val cl = getClass.getClassLoader (来自构建定义类)的预期行为,因为该类加载器包含所有构建定义、插件和依赖项。此外,它还有效地使上述步骤1的行为类似于步骤2。
不过,最后,我决定只通过调用上下文类加载器( ActorSystem )来创建ActorSystem("someName", ConfigFactory.load(cl), cl),而不接触上下文类加载器,这看起来更干净(对于我这样不知道上下文类加载器是什么或做什么的人来说,这似乎不那么可怕)。
TL;博士
val system = ActorSystem()写
val cl = getClass.getClassLoader
val system = ActorSystem("mySystem", ConfigFactory.load(cl), cl)https://stackoverflow.com/questions/20429568
复制相似问题