2016-11-21 10 views
4

TL影アッカライブラリのreference.confを構成する方法、DRを

私は日陰にakkaライブラリのバージョンをしようと私のアプリケーションとの同梱しています(spray-canを実行できるようにしますサーバーCDH 5.7バージョンSpark 1.6)。シェーディング処理messes up akka's default configurationakkareference.confの別のバージョンを影付きのakkaに手動で提供した後も、2つのバージョンが何らかの形で混乱しているように見えます。スカラ+ SBT -

シェーディングakkaは問題を引き起こすことが知られていますか?私は間違って何をしていますか?

背景

私は現在、Spark 1.6.1スタンドアロンで実行されているScala/Sparkアプリケーションを持っています。アプリケーションは、akka 2.3.9Spark 1.6.1スタンドアロンにはakka 2.3.11を含む)を必要とするspray 1.3.3を使用してspray-can httpサーバーを実行します。

私は Spark 1.6CDH 5.7バージョンを実行して新しい Clouderaベース Sparkクラスタにアプリケーションを移行しようとしています。問題は、の Spark 1.6akka 2.2.3にバンドルされており、 spray 1.3.3が正しく機能するには不十分です。

未遂ソリューション

this postでの提案に続いて、私は日陰akka 2.3.9に決め、自分のアプリケーションと一緒に同梱。今回は新しい問題が発生しましたが、akkaは、アプリケーションのクラスパス上にあるreference.confファイルで定義されているデフォルト構成を持っています。 sbt-assemblyのシェーディング機能でknown issueがあるため、影付きのakkaライブラリには別の設定が必要なようです。

だから、私は以下のシェードルールにakkaを遮光終わった。しかし、すべてのoccurancesと、

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

akkareference.confオリジナルと同じです私のプロジェクト、で追加reference.confファイルを含みます " akka "は" akka_2_3_9_shade "に置き換えられました。

さて、しかし、Sparkが、私は次のエラーを取得していますようakkaは、影akkaで何とかアップ混入-providedようだ:

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

OK、結局私はこの問題を解決しました。

文字列リテラルとして定義されているキーを使用して、設定ファイルから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のオリジナルreference.confの内容(これは、ハードコードされた文字列リテラル設定キーのために必要とされる)が、設定値にakkaプレフィックスを有するakka_2_3_9_shadeに変更し、ルート設定キーを有することにakkaからを変更しましたakka_2_3_9_shade
  • sprayのオリジナルreference.confの内容(これはsbt-assemblyによって修飾を受けるか設定キーのために必要とされる)が、akka_2_3_9_shadeに変更設定値にakkaプレフィックスを有します。

    val akkaShadeConfig = ConfigFactory.load("akka_spray_shade") 
    implicit val system = ActorSystem("custom-actor-system-name", akkaShadeConfig) 
    
    :今

(これはsprayが常に日陰akkaを指していることを確認するために必要とされる)、このカスタム設定ファイルは、アプリケーションのBoot.scalaコードでActorSystemの初期化中に明示的にを提供しなければなりません

+0

このハックは機能しますが、akkaキーが変更された場合、または独自のakka設定を導入しても幸運です。適切な解決策は、構成キーをプログラムで「シェード」することです。 'sbt-assembly'はまだそのような機能を提供していないようです。おそらくそれはsbtを介して自分自身を行うことが可能です。 – juanmirocks

1

受け入れられた答えに少し追加。

akka_spray_shade.confのようなカスタム名前付きファイルにこの設定を入れる必要はありません。構成は、ActorSystemの作成時にデフォルトでロードされているapplication.confに配置することができます。具体的にはカスタム構成が指定されていない場合ActorSystem("custom-actor-system-name")は実質的にActorSystem("custom-actor-system-name", ConfigFactory.load("application"))を意味します。