运行Scala的jar文件时出现NoClassDefFoundError错误

10

我有一个使用RemoteActors的小应用程序,我想从中制作一个jar文件。当我尝试执行它时,会出现以下异常:

Exception in thread "main" java.lang.reflect.InvocationTargetException
  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:616)
  at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.NoClassDefFoundError: scala/actors/Combinators
  at pingpong.PingApp$.main(PingApp.scala:5)
  at pingpong.PingApp.main(PingApp.scala)
  at pingpong.ScalaEntryPoint.main(ScalaEntryPoint.java:5)
  ... 5 more
Caused by: java.lang.ClassNotFoundException: scala.actors.Combinators
  at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
  ... 8 more

我已经将scala-library.jar包含在我的jar文件中,并将其加入了类路径。否则java会在找不到类ScalaObject时停止。


更多的运行时信息会很有帮助。你是想用Maven构建一个jar包吗?还是只是在Eclipse中运行它? - hellectronic
1
至少要展示你调用的命令行,并提到你使用的Scala版本。 - retronym
命令:java -jar myjar.jar 我正在使用Scala 2.7.7最终版。 - laci37
2.7.7是什么原因呢?Combinators在scala-library.jar中,所以这是一个类路径问题。尝试将library.jar显式添加到类路径中。 - aishwarya
2个回答

5

Java无法处理“jar within a jar”。默认的类加载器无法以这种方式加载类。

从您的堆栈跟踪中看,似乎您使用了eclipse的导出->java->可运行jar。它应该包括一个特殊的类加载器,可以处理jar in jar加载,但似乎没有起作用。

我猜测构建jar时出了问题,或者由于scala同时包含在您的jar和classpath中而感到困惑。您可以尝试再次使用“提取库到jar”而不是“将库打包到jar”。您可以尝试在classpath上没有scala的情况下进行尝试。

如果失败,则有其他选项可用于生成单个可运输的jar:

  • 您可以解压缩所有依赖的jar并重新打包它们以及您编译的类(应该是上面“extract”所做的)。Maven的shade插件可以帮助完成此操作。

  • 您可以使用另一种解决方案,它将提供一个可以加载嵌套jar的类加载器实现,例如OneJar

希望这对您有用,如果您需要更多帮助,您需要描述生成此jar的确切步骤,"jar tvf myjar.jar" 的输出可能也会有所帮助。

我尝试将Scala库提取到JAR文件中,但结果仍然是相同的异常。似乎在scala-library.jar中没有scala.actors.Combinators类。 - laci37
你能运行 "jar tvf myjar.jar" 并确保 scala-lang 被显示在其中吗?如果是这样的话,将 myjar.jar 解压缩 (jar xvf) 到一个临时文件夹中,然后以同样的方式检查存在的 scala-lang.jar? - Brian Smith
jar tvf ping.jar | grep scala-lang 没有显示任何结果。我已经提取了该jar文件,但没有找到任何名为scala-lang的文件。 - laci37
1
这意味着无论你采取什么步骤来包含它,它都没有被包含,因此会出现ClassNotFoundException。最好向eclipse.org提出这个问题。同时,我建议您使用maven的shade插件、OneJar或将其包含在运行时类路径中。 - Brian Smith

1
问题是Eclipse上的Scala插件与安装的Scala版本不匹配。actors/Combinators.scala出现在2.8中,而Eclipse插件是2.8,但我却包含了2.7.7 scala-library.jar文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接