2016-11-21 81 views
4

TL; DR

我試圖遮蔭一個版本的akka庫,並與我的應用程序中捆綁它(能夠運行一個spray-can服務器上的CDH 5.7版本的Spark 1.6)。着色過程messes up akka's default configuration,並且在爲着色的akka手動提供akkareference.conf的單獨版本之後,它仍然看起來像2個版本以某種方式混淆。斯卡拉+ SBT - 如何配置reference.conf的陰影阿卡庫

是否着色akka已知會導致問題的版本?我究竟做錯了什麼?

背景

我有一個Scala/Spark應用目前Spark 1.6.1獨立運行。該應用程序使用spray 1.3.3運行spray-can http服務器,該服務器需要akka 2.3.9Spark 1.6.1獨立包含兼容的akka 2.3.11)。

我想給應用程序遷移到運行CDH 5.7版本的Spark 1.6Cloudera基於Spark集羣。問題是,Spark 1.6CDH 5.7akka 2.2.3捆綁在一起,這不足以使spray 1.3.3正常工作。

嘗試性解決方案

this post的建議,我決定遮陽akka 2.3.9和捆綁它與我的應用程序一起。雖然這次我偶然發現了一個新問題 - akkareference.conf文件中定義了它的默認配置,它應該位於應用程序的類路徑中。由於sbt-assemblyknown issue的着色功能,看起來陰影的akka庫需要單獨的配置。

所以,我結束了陰影akka具有以下遮陽規則:

ShadeRule.rename("akka.**" -> "[email protected]") 
    .inLibrary("com.typesafe.akka" % "akka-actor_2.10" % "2.3.9") 
    .inAll 

,並且包含附加reference.conf文件在我的項目,這是相同的akka的原始reference.conf,但與所有出現「 akka「替換爲」akka_2_3_9_shade「。

但現在,似乎Spark -provided akka獲取與陰影akka混合起來弄好了,因爲我發現了以下錯誤:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate MailboxType [akka.dispatch.UnboundedMailbox], defined in [akka.actor.default-mailbox], make sure it has a public constructor with [akka.actor.ActorSystem.Settings, com.typesafe.config.Config] parameters 
    at akka_2_3_9_shade.dispatch.Mailboxes$$anonfun$1.applyOrElse(Mailboxes.scala:197) 
    at akka_2_3_9_shade.dispatch.Mailboxes$$anonfun$1.applyOrElse(Mailboxes.scala:195) 
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) 
    at scala.util.Failure$$anonfun$recover$1.apply(Try.scala:185) 
    at scala.util.Try$.apply(Try.scala:161) 
    at scala.util.Failure.recover(Try.scala:185) 
    at akka_2_3_9_shade.dispatch.Mailboxes.lookupConfiguration(Mailboxes.scala:195) 
    at akka_2_3_9_shade.dispatch.Mailboxes.lookup(Mailboxes.scala:78) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider.akka$actor$LocalActorRefProvider$$defaultMailbox$lzycompute(ActorRefProvider.scala:561) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider.akka$actor$LocalActorRefProvider$$defaultMailbox(ActorRefProvider.scala:561) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider$$anon$1.<init>(ActorRefProvider.scala:568) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider.rootGuardian$lzycompute(ActorRefProvider.scala:564) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider.rootGuardian(ActorRefProvider.scala:563) 
    at akka_2_3_9_shade.actor.LocalActorRefProvider.init(ActorRefProvider.scala:618) 
    at akka_2_3_9_shade.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:619) 
    at akka_2_3_9_shade.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:616) 
    at akka_2_3_9_shade.actor.ActorSystemImpl._start(ActorSystem.scala:616) 
    at akka_2_3_9_shade.actor.ActorSystemImpl.start(ActorSystem.scala:633) 
    at akka_2_3_9_shade.actor.ActorSystem$.apply(ActorSystem.scala:142) 
    at akka_2_3_9_shade.actor.ActorSystem$.apply(ActorSystem.scala:109) 
    at akka_2_3_9_shade.actor.ActorSystem$.apply(ActorSystem.scala:100) 
    at MyApp.api.Boot$delayedInit$body.apply(Boot.scala:45) 
    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 MyApp.api.Boot$.main(Boot.scala:28) 
    at MyApp.api.Boot.main(Boot.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:601) 
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731) 
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) 
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206) 
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) 
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 
Caused by: java.lang.ClassCastException: interface akka_2_3_9_shade.dispatch.MailboxType is not assignable from class akka.dispatch.UnboundedMailbox 
    at akka_2_3_9_shade.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:69) 
    at akka_2_3_9_shade.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:66) 
    at scala.util.Try$.apply(Try.scala:161) 
    at akka_2_3_9_shade.actor.ReflectiveDynamicAccess.getClassFor(DynamicAccess.scala:66) 
    at akka_2_3_9_shade.actor.ReflectiveDynamicAccess.CreateInstanceFor(DynamicAccess.scala:84) 
    ... 34 more 

從我的應用程序的Boot.scala文件中的相關代碼如下:

[45] implicit val system = ActorSystem() 
... 
[48] val service = system.actorOf(Props[MyAppApiActor], "MyApp.Api") 
... 
[52] val port = config.getInt("MyApp.server.port") 
[53] IO(Http) ? Http.Bind(service, interface = "0.0.0.0", port = port) 

回答

6

好的,所以最終我設法解決了這個問題。

變爲akka使用定義爲字符串文字的鍵從配置文件中加載(一些)配置設置。例如,您可以在akka/actor/ActorSystem.scala中找到很多。

而且似乎sbt-assembly不會更改對字符串文字中陰影庫/包名稱的引用。

另外,一些配置鍵sbt-assembly的陰影所改變。我沒有真正花時間找到它們在akka的源代碼中的定義以及它們的確切位置,但在ActorSystem初始化代碼期間拋出的以下異常證明確實如此:

ConfigException$Missing: No configuration setting found for key 'akka_2_3_9_shade' 

因此,該解決方案也包括一個自定義的配置文件(稱之爲例如akka_spray_shade.conf),並在將其複製的以下構成部分:

  • akka的原reference.conf的內容,但是具有akka配置值中的前綴更改爲akka_2_3_9_shade。 (這是所必需的硬編碼的字符串文字配置鍵)
  • akka的原reference.conf的內容,但是具有在配置值的akka前綴改變爲akka_2_3_9_shade並且具有根配置密鑰改變akkaakka_2_3_9_shade。 (這是配置密鑰所需的修改sbt-assembly
  • spray的原始reference.conf的內容,但配置值中的akka前綴更改爲akka_2_3_9_shade

    val akkaShadeConfig = ConfigFactory.load("akka_spray_shade") 
    implicit val system = ActorSystem("custom-actor-system-name", akkaShadeConfig) 
    
    :(這是必需的,以確保spray總是指陰影akka

現在,這個自定義配置文件必須在ActorSystem的應用程序的Boot.scala代碼初始化期間提供明確

+0

這個黑客行得通,但如果阿卡鍵改變,或者即使你引入了你自己的akka​​設置,祝你好運。正確的解決方案是以編程方式「配置」密鑰。 'sbt-assembly'似乎還沒有提供這樣的功能;也許可以通過sbt做自己。 – juanmirocks

1

接受答案的一小部分。

沒有必要將此配置放在一個自定義文件中,如akka_spray_shade.conf。配置可以被放置在application.conf中,在默認情況下在ActorSystem創建時加載,當沒有明確指定自定義配置時:ActorSystem("custom-actor-system-name")實際上意味着ActorSystem("custom-actor-system-name", ConfigFactory.load("application"))