Scala Lambda仅在AWS中失败

问题描述

我正在编写我的第一个scala lambda,并且在本地所有连接都可以正常工作。但是,当我尝试在AWS中测试lambda时,出现以下错误

{
  "errorMessage": "Error loading class FooBar.Main: scala/collection/Seq","errorType": "java.lang.NoClassDefFoundError"
}

从谷歌搜索看来,这似乎是因为我需要将scala库添加到我的依赖项中。

name := "FooBar"
version := "0.1"
scalaVersion := "2.12.12"
javacoptions ++= Seq("-source","1.8","-target","-Xlint")
lazy val root = (project in file(".")).
settings(
  name := "FooBar",version := "1.0",scalaVersion := "2.12.12",retrieveManaged := true
)
libraryDependencies += "software.amazon.awssdk" % "ec2" % "2.5.60"
libraryDependencies += "com.amazonaws" % "aws-lambda-java-core" % "1.2.0"
libraryDependencies += "com.amazonaws" % "aws-lambda-java-events" % "2.1.0"
libraryDependencies += "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.313"
libraryDependencies += "org.scalikejdbc" %% "scalikejdbc" % "3.4.0"
libraryDependencies += "org.apache.phoenix" % "phoenix-core" % "4.14.3-HBase-1.4"
libraryDependencies += "org.apache.hbase" % "hbase-common" % "1.4.10"
libraryDependencies += "org.apache.hbase" % "hbase-server" % "1.4.10"
libraryDependencies += "io.spray" %%  "spray-json" % "1.3.2"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
libraryDependencies += "org.scala-lang" % "scala-library" % "2.12.12"

assemblyShadeRules in assembly := Seq(
  ShadeRule.keep("x.**").inAll,ShadeRule.keep("FooBar.**").inProject
)

assemblyMergeStrategy in assembly := {
  case PathList("meta-inf",xs@_*) => MergeStrategy.discard
  case x => MergeStrategy.first
}
再次

,一切在本地都可以正常运行,只是永远无法在AWS上执行。有人有主意吗?

解决方法

sbt-assembly插件阴影规则ShadeRule.keep文档说明

ShadeRule.keep规则将所有匹配的类标记为“根”。如果有的话 定义了保留规则,这些规则不能从 写入输出时,通过依赖关系分析的根将被丢弃 罐子。

https://github.com/sbt/sbt-assembly#shading

因此,在这种情况下,创建胖子罐时将保留类路径x.*FooBar.*的所有类。其余所有其他类(包括scala库中的类)都将被丢弃。

要解决此问题,请删除所有ShadeRule.keep规则,而改为尝试ShadeRule.zap选择性地丢弃不需要的类。

例如,以下阴影规则从远端jar中删除所有HDFS类:

  assemblyShadeRules in assembly := Seq(
    ShadeRule.zap("org.apache.hadoop.hdfs.**").inAll
  )

PS:解压缩胖子之后,AWS Lambda的代码大小硬限制为256MB。