尝试使用jar时Scala NoClassDefFoundError

时间:2013-05-24 07:05:58

标签: scala jar compilation classpath noclassdeffounderror

首先我克隆了scopt并创建了一个jar:

git clone git://github.com/scopt/scopt.git
sbt package-bin

然后我创建了一个文件ArgTest.scala(使用scopt示例):

case class Config(foo: Int = -1, bar: String = "", xyz: Boolean = false,
  libname: String = "", libfile: String = "", maxlibname: String = "",
  maxcount: Int = -1, whatnot: String = "")

object ArgTest {
  def main(args: Array[String]) {
    val parser = new scopt.immutable.OptionParser[Config]("scopt", "2.x") { def options = Seq(
      intOpt("f", "foo", "foo is an integer property") { (v: Int, c: Config) => c.copy(foo = v) },
      opt("o", "output", "output") { (v: String, c: Config) => c.copy(bar = v) },
      booleanOpt("xyz", "xyz is a boolean property") { (v: Boolean, c: Config) => c.copy(xyz = v) },
      keyValueOpt("l", "lib", "<libname>", "<filename>", "load library <libname>")
        { (key: String, value: String, c: Config) => c.copy(libname = key, libfile = value) },
      keyIntValueOpt(None, "max", "<libname>", "<max>", "maximum count for <libname>")
        { (key: String, value: Int, c: Config) => c.copy(maxlibname = key, maxcount = value) },
      arg("<file>", "some argument") { (v: String, c: Config) => c.copy(whatnot = v) }
    ) }
    // parser.parse returns Option[C]
    parser.parse(args, Config()) map { config =>
      // do stuff
    } getOrElse {
      // arguments are bad, usage message will have been displayed
    }
  }
}

然后我尝试编译并运行它:

scalac .\ArgTest.scala -cp ".\scopt_2.10-2.1.0.jar"
scala ArgTest -cp ".\scopt_2.10-2.1.0.jar"

我收到了这个错误:

java.lang.NoClassDefFoundError: scopt/generic/GenericOptionParser
        at ArgTest.main(ArgTest.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
        at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
        at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Caused by: java.lang.ClassNotFoundException: scopt.generic.GenericOptionParser
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.scala$tools$nsc$util$ScalaClassLoader$$super$findClass(ScalaClassLoader.scala:88)
        at scala.tools.nsc.util.ScalaClassLoader$class.findClass(ScalaClassLoader.scala:44)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.findClass(ScalaClassLoader.scala:88)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.scala$tools$nsc$util$ScalaClassLoader$$super$loadClass(ScalaClassLoader.scala:88)
        at scala.tools.nsc.util.ScalaClassLoader$class.loadClass(ScalaClassLoader.scala:50)
        at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.loadClass(ScalaClassLoader.scala:88)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 16 more

你认为我错过了什么?

1 个答案:

答案 0 :(得分:2)

(首先参见我上面关于sbt的评论)

scala ArgTest -cp ".\scopt_2.10-2.1.0.jar"

这将使用参数ArgTest运行-cp ".\scopt_2.10-2.1.0.jar"。要使这些参数被Scala本身解析为编译器选项,它们需要首先出现:

 $ scala -help
Usage: scala <options> [<script|class|object|jar> <arguments>]
...

所以你需要

scala -cp .\scopt_2.10-2.1.0.jar:. ArgTest