Joh*_*sch 4 akka sbt-assembly apache-spark cloudera-cdh shading
我试图遮蔽akka
库的一个版本并将其与我的应用程序捆绑在一起(以便能够spray-can
在CDH 5.7
版本上运行服务器Spark 1.6
).着色过程混淆了akka
默认配置,并且在为阴影手动提供单独版本的akka
s之后,看起来仍然看起来两个版本以某种方式混淆了.reference.conf
akka
是否akka
已知阴影版本会导致问题?我究竟做错了什么?
我有一个Scala
/ Spark
应用程序当前在Spark 1.6.1
独立运行.应用程序使用spray-can
http服务器运行spray 1.3.3
,这需要akka 2.3.9
(Spark 1.6.1
独立包括兼容akka 2.3.11
).
我正在尝试将应用程序迁移到运行该版本的新的Cloudera
基于Spark
群集的群集.问题是,在与捆绑这是不足够的正常工作.CDH 5.7
Spark 1.6
Spark 1.6
CDH 5.7
akka 2.2.3
spray 1.3.3
根据这篇文章中的建议,我决定将akka 2.3.9
它与我的应用程序一起进行着色并捆绑.虽然这次我偶然发现了一个新问题 - akka
它是否在reference.conf
文件中定义了默认配置,该文件应该位于应用程序的类路径中.由于着色功能中的已知问题,sbt-assembly
阴影akka
库似乎需要单独的配置.
所以,我最终akka
使用以下阴影规则进行着色:
ShadeRule.rename("akka.**" -> "akka_2_3_9_shade.@1")
.inLibrary("com.typesafe.akka" % "akka-actor_2.10" % "2.3.9")
.inAll
Run Code Online (Sandbox Code Playgroud)
并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
Run Code Online (Sandbox Code Playgroud)
我的应用程序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)
Run Code Online (Sandbox Code Playgroud)
好的,所以最终我设法解决了这个问题.
akka
使用定义为字符串文字的键从配置文件中输出加载(某些)配置设置.例如,你可以找到很多这些akka/actor/ActorSystem.scala
.
并且似乎sbt-assembly
不会更改字符串文字中对着色库/包名称的引用.
此外,一些配置键都被改变sbt-assembly
的阴影.我没有真正花时间在akka
源代码中找到它们的定义位置和方式,但是在ActorSystem
init代码中抛出的以下异常证明了确实如此:
ConfigException$Missing: No configuration setting found for key 'akka_2_3_9_shade'
Run Code Online (Sandbox Code Playgroud)
因此,解决方案包括自定义配置文件(例如akka_spray_shade.conf
,调用它),并在其中复制以下配置部分:
akka
原始内容reference.conf
,但akka
配置值中的前缀更改为akka_2_3_9_shade
.(这是硬编码字符串文字配置键所必需的)akka
的原始reference.conf
的,但具有akka
在配置值的前缀改变为akka_2_3_9_shade
和具有改变的根构造密钥从akka
到akka_2_3_9_shade
.(这是需要修改的配置键所必需的sbt-assembly
)spray
原始内容reference.conf
,但akka
配置值中的前缀更改为akka_2_3_9_shade
.(这是确保spray
始终引用阴影所必需的akka
)现在,必须在应用程序代码的初始化期间显式提供此自定义配置文件:ActorSystem
Boot.scala
val akkaShadeConfig = ConfigFactory.load("akka_spray_shade")
implicit val system = ActorSystem("custom-actor-system-name", akkaShadeConfig)
Run Code Online (Sandbox Code Playgroud)