joda DateTimeFormat的NoClassDefFoundError

时间:2014-07-07 22:07:57

标签: java scala sbt jodatime apache-spark

我正在尝试在我使用sbt作为构建工具的Spark项目(在Scala中)中使用joda的DateTimeFormat,当我尝试将其作为独立应用程序运行时,它给了我一个java.lang.NoClassDefFoundError 。这对我来说似乎很奇怪,因为我在控制台中使用它时没有出现任何错误,但是当我尝试将其作为应用程序运行时,它会出错

Exception in thread "main" java.lang.NoClassDefFoundError: org/joda/time/format/DateTimeFormat
    at com.bdcoe.poc.spark.analytics.Driver$.main(Driver.scala:35)
    at com.bdcoe.poc.spark.analytics.Driver.main(Driver.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:292)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:55)
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: org.joda.time.format.DateTimeFormat
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 9 more

这是我的build.sbt文件,它位于项目的根目录中:

import AssemblyKeys._
import net.virtualvoid.sbt.graph.Plugin.graphSettings

organization := "com.bdcoe.poc"

name := "spark-analytics"

scalaVersion := "2.10.4"

resolvers ++= Seq(
  "Local Maven" at Path.userHome.asFile.toURI.toURL + ".m2/repository"
)

libraryDependencies ++= {
  val slf4jVersion = "1.7.7"
  Seq(
    "org.apache.spark" %% "spark-core" % "1.0.0",
    "com.github.nscala-time" %% "nscala-time" % "1.2.0",
    "org.scalatest" %% "scalatest" % "2.0" % "test",
    "org.slf4j" % "slf4j-api" % slf4jVersion % "provided",
    "org.slf4j" % "slf4j-nop" % slf4jVersion % "test",
    "joda-time" % "joda-time" % "2.2", 
    "org.joda" % "joda-convert" % "1.2"
  )
}

这是我对joda的导入/使用:

import org.joda.time.format.DateTimeFormat.{ forPattern => formatFor }

val dateTime = formatFor("YYYY-MM-dd HH:mm").parseDateTime _ 
val timeStamp: DateTime = dateTime(args(2))

有关为什么它可以在sbt控制台中找到joda而不是作为独立应用程序运行时的任何建议?

2 个答案:

答案 0 :(得分:1)

问题在于运行时的类路径。

我注意到您正在使用sbt-assembly。在assemblySettings

中导入后添加此build.sbt
import AssemblyKeys._
import net.virtualvoid.sbt.graph.Plugin.graphSettings

assemblySettings

organization := "com.bdcoe.poc"

...

如文档中所述:https://github.com/sbt/sbt-assembly。 Sbt-assembly将找到主类并使用正确配置的清单打包JAR。

请注意,您应该运行的任务是assembly,而不是package。如果项目中没有assemblySettings,您将无法先运行此任务,并且由于您正在运行打包的JAR(最有可能),因此您必须使用package任务生成它,并且不是assembly

答案 1 :(得分:0)

您需要在运行时安排包含org.joda类的JAR文件在CLASSPATH中。控制台已经为你完成了这个,它找到了类,一切都运行了。问题是当在命令行上运行时,系统没有找到包含该类的JAR,并且无法加载该类。