sbt - 在 SBT 构建任务 : reference configuration unexpectedly missing 中运行 akka

标签 sbt akka

我试图在我为 SBT 构建编写的任务中运行一个相当简单的 HTTP POST 请求,并且看到 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 如何管理其运行构建的类路径有关。

一些精度:我使用的是 SBT 0.13.0(因此构建代码使用 Scala 2.10)并且我已经检查过上述 akka-actor jar 确实包含一个符合预期的 reference.conf 文件。在查看我猜测可能与构建执行类路径(reload plugins 然后是 show runtime:fullClasspath 在 sbt 中)相关的内容时,该 jar 出现在列表中。

我也没有在谷歌上搜索任何相关的东西,无法传达问题在于从 SBT 构建中运行 akka。

最后,我真的不知道 'akka' 配置 key 是如何丢失的。任何人都可以帮忙吗?

最佳答案

akka 真正令人讨厌的是,您需要为通用设置更新线程本地上下文类加载器,而很多工具(如 sbt)则不需要,因为它们不知道您正在运行哪个线程或您使用的是哪个类加载器将需要。

这是an example from the activator build :

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.getContextClassLoader
  • getClassLoader在非 Akka 堆栈的类上将调用堆栈框架向上
  • ActorSystem.getClass.getClassLoader

  • 所以这就是上述改变上下文类加载器的解决方案有效的原因。

    至于在实践中使用的类加载器,我得到了预期的行为 val cl = getClass.getClassLoader (来自我的构建定义类)因为该类加载器包含所有构建定义、插件和依赖项。它还有效地使上面的第 1 步表现得像第 2 步。

    尽管如此,我最终还是通过调用 ActorSystem("someName", ConfigFactory.load(cl), cl) 创建了 ActorSystem。并且不涉及上下文类加载器,这似乎更清晰(对于像我这样不知道上下文类加载器是什么或做什么的人来说,这不那么可怕)

    TL;博士 代替
    val system = ActorSystem()
    


    val cl = getClass.getClassLoader
    val system = ActorSystem("mySystem", ConfigFactory.load(cl), cl)
    

    关于sbt - 在 SBT 构建任务 : reference configuration unexpectedly missing 中运行 akka,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20429568/

    相关文章:

    scala - 我如何更改 sbt 使用的 Scala 版本?

    scala - 使用 Akka 在一天中的固定时间安排任务

    scala - spark停止时如何清理其他资源

    c# - ActorSelection 的 Akka.net 死锁问题

    scala - Akka Stream 从 Sink 返回对象

    scala - SBT 0.13 Build.scala 引用未定义的设置

    scala - 未能在 build.sbt 中包含 com.typesafe(对于 Scala 和 Heroku 上的 Spray)

    scala - SBT 项目发布 2 个工件的惯用方式是什么?

    scala - 为什么 sbt 控制台在多模块项目中看不到来自子项目的包?

    java - 向 parent 的 child Actor 发送消息并等待结果