Scala 使用SBT创建的Uber/Fat Jar上的NoClassDefFoundError
我正在使用Scala 使用SBT创建的Uber/Fat Jar上的NoClassDefFoundError,scala,log4j,sbt,sbt-assembly,Scala,Log4j,Sbt,Sbt Assembly,我正在使用sbt-assembly插件创建Uber/Fatjar。但是获得以下异常 scala -cp ./target/scala-2.11/test.jar com.LoggingTest java.lang.NoClassDefFoundError: org/apache/log4j/Logger at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclar
sbt-assembly
插件创建Uber/Fat
jar。但是获得以下异常
scala -cp ./target/scala-2.11/test.jar com.LoggingTest
java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
我已经将log4j
作为依赖项的一部分(参考下面的build.sbt
文件)。不确定为什么我仍然收到NoClassDefFoundError
lazy val root = (project in file(".")).
settings(
name := "myproject",
version := "1.0",
scalaVersion := "2.11.8",
libraryDependencies ++= Seq(
"org.apache.logging.log4j" % "log4j-api" % "2.8",
"org.apache.logging.log4j" % "log4j-core" % "2.8",
"org.apache.logging.log4j" %% "log4j-api-scala" % "2.8"
)
)
// Adding scala style to compilation process
lazy val compileScalastyle = taskKey[Unit]("compileScalastyle")
compileScalastyle := org.scalastyle.sbt.ScalastylePlugin.scalastyle.in(Compile).toTask("").value
(compile in Compile) <<= (compile in Compile) dependsOn compileScalastyle
assemblyMergeStrategy in assembly := {
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.last
case PathList("javax", "activation", xs @ _*) => MergeStrategy.last
case PathList("javax", "el", xs @ _*) => MergeStrategy.last
case PathList("org", "apache", xs @ _*) => MergeStrategy.last
case PathList("com", "google", xs @ _*) => MergeStrategy.last
case PathList("com", "esotericsoftware", xs @ _*) => MergeStrategy.last
case PathList("com", "codahale", xs @ _*) => MergeStrategy.last
case PathList("com", "yammer", xs @ _*) => MergeStrategy.last
case PathList("org", "jboss", xs @ _*) => MergeStrategy.last
case PathList("io", "netty", xs @ _*) => MergeStrategy.discard
case "about.html" => MergeStrategy.rename
case "META-INF/ECLIPSEF.RSA" => MergeStrategy.last
case "META-INF/mailcap" => MergeStrategy.last
case "META-INF/mimetypes.default" => MergeStrategy.last
case "META-INF/jboss-beans.xml" => MergeStrategy.last
case "plugin.properties" => MergeStrategy.last
case "log4j.properties" => MergeStrategy.last
case "project.properties" => MergeStrategy.last
case "META-INF/io.netty.versions.properties" => MergeStrategy.last
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
我还解压缩了jar,发现类(org.apache.log4j.logger.logger
)在jar中不可用。我希望该类在Jar中可用,因为log4j
已作为sbt
依赖项的一部分添加。我确实找到了类org.apache。
日志记录.log4j.Logger
PS:我也在为一些类执行jar
使用spark submit
(因为我在使用spark
api进行一些计算),它可以正常工作您还可以为您的项目显示sbt assembly
插件设置吗,我假设您使用sbt assembly
任务创建了test.jar
?无论哪种方式,JAR文件都只是一个具有不同扩展名的zip文件。如果复制并重命名它test.zip
,则可以解压缩它并检查其内容。鉴于您看到的错误,我希望您在提取的内容中找不到org/apache/log4j/Logger.class
文件。@Mikealen是的,我确实使用sbt assembly
命令创建了Jar(而不是sbt assembly
)。我还用我完整的sbt
文件内容(包括合并策略)以及plugins.sbt
的内容更新了这个问题。正如您所说,jar文件没有类。考虑到我在sbt
dependencyWhoops中添加了log4j
,不知是什么原因导致了这种情况!你说得对,它是sbt组件。对不起,有什么困惑。我现在只是看一下您的设置……对于每个JAR文件都具有相同名称的文件,使用“合并策略”,因此在合并到生成的fat JAR文件中时会发生冲突。我认为您不需要列出所有文件,尤其是在没有冲突的情况下。此外,我认为任何程序集设置都必须包含在根项目中(作为公共设置,或者只是重新定位到该项目的设置下)才能生效。最后,没有指示将输出命名为test.jar
,那么您要复制哪个文件来创建该文件?
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0")