可怕的java.lang.NoClassDefFoundError

5
我查看了许多关于这个错误的现有线程,但仍然没有成功。 我甚至没有尝试打包jar文件或使用任何第三方打包工具。 我只是在Eclipse中运行(非常好用),然后尝试在命令行中从同一位置运行完全相同的应用程序(获取此错误)。 我的目标是能够压缩bin文件夹并通过命令行脚本发送给其他人运行。 一些细节如下:
  • 这是一个命令行应用程序,我正在使用commons-lang-2.4.jar进行字符串操作。 那是无法定位的文件(特别是“java.lang.NoClassDefFoundError:org / apache / commons / lang / StringEscapeUtils”)
  • 我将该jar文件放在我的lib文件夹中,并通过右键单击“Build Path-> Add to Build Path”将其添加到Eclipse的构建路径中
  • .classpath文件看起来正确,并包含对jar的引用,但我认为该文件仅由Eclipse使用(包含此行:<classpathentry kind="lib" path="lib/commons-lang-2.4.jar"/>
  • 这可能与Eclipse工作目录设置有关吗? 我有一些内部模板文件,它们位于src / templates下,我唯一能够看到它们的方法是将项目工作目录设置为AppName / src。 也许我应该将它们放在其他地方?
如果有任何其他信息可以帮助,请告诉我。 当然,这很简单,但是我已经浪费了太多时间了。 这让我想起了为什么我最初在05年左右离开Java...

1
你的命令行脚本是什么样子的?在这个脚本中,你必须明确设置类路径。 - MarkPowell
请问您能展示一下输入的命令行指令以运行该应用程序吗? - Tendayi Mawushe
我还没有脚本,但请看下面我给BalusC的评论,了解我现在正在使用的命令(可以工作,但现在出现了权限被拒绝的问题)。 - Brian Moeskau
7个回答

13

NoClassDefFoundError的意思是,在编译时,类在classpath里存在,但在运行时却不存在。

在您的情况下,使用java.exe从命令行执行时,您需要在-cp-classpath参数中指定classpath。或者如果它是一个JAR文件,则需要在其MANIFEST.MF文件的class-path条目中指定它。

参数/条目的值可以是绝对或相对文件系统路径,指向包含所有.class文件或单个.jar文件的文件夹。您可以使用分号;分隔路径。当路径包含空格时,您需要用双引号"将特定路径括起来。例如:

java -cp .;c:/path/to/file.jar;"c:/spacy path/to/classes" mypackage.MyClass
为了节省在命令行中输入和编辑参数的工作量,可以使用一个名为.bat文件。 编辑: 我应该意识到您正在使用基于Unix的操作系统。上面的例子是针对Windows的。对于类似Unix的平台,您可以遵循相同的规则,但需要使用冒号:分隔路径,而不是批处理文件,使用一个名为.sh的文件。
java -cp .:/path/to/file.jar:"/spacy path/to/classes" mypackage.MyClass

这让我接近了。现在我正在使用这个命令:java -cp bin;lib/commons-lang-2.4.jar bin/AppName -- 现在我得到了“lib/commons-lang-2.4.jar: Permission denied”的错误信息? - Brian Moeskau
@bmoeskau:这更像是操作系统级别的限制。请检查文件权限。 - BalusC
我应该提到我在Mac(unix)上。安全错误是因为它实际上试图不正确地执行jar文件。Unix需要使用冒号“:”而不是分号“;”作为路径分隔符。这似乎有效:java -cp bin:lib/commons-lang-2.4.jar AppName现在我遇到了不同的错误,但我认为这解决了我的原始问题,所以我接受了你的答案。谢谢! - Brian Moeskau
顺便提一下,新的错误是找不到一些内部模板文件的路径。将代码更改为使用getResource(),现在它运行得非常好 - 再次感谢。 - Brian Moeskau
谢谢您的提示,非常有帮助。 - Meow
显示剩余4条评论

6
你是否在命令行中指定了Java的类路径?
$ java -cp lib/commons-lang-2.4.jar your.main.Class

2
您在Eclipse中设置的类路径仅适用于IDE,并不影响应用程序在IDE之外的运行方式。即使您使用Eclipse功能将应用程序导出为可执行的jar文件,也没有现成的方法来打包应用程序所依赖的所有jar文件。
如果您已将应用程序打包到名为myapp.jar的jar文件中,则运行以下命令将使用您所依赖的jar文件运行应用程序;如果您有多个,请在Windows上使用分号;或在Unix上使用冒号:将它们分开添加:
java -jar myapp.jar -cp .;c:/pathtolibs/commons-lang-2.4.jar

如果您只是直接运行类,那么运行包含您的.class文件的文件夹也需要在路径上(尽管我假设它已经在路径上,因为您能够运行程序并获得错误信息)。


1
考虑使用“文件”->“导出”->“可运行的JAR文件”来创建一个可以直接调用的JAR文件。
java -jar yourProgram.jar

根据您的需求,有几种变体可供选择。


我也尝试过这个,但是在这种情况下,我的应用程序内部会出现一个错误,即找不到我的自定义模板文件夹(在Eclipse的/src下)。不确定资源路径如何与JAR文件一起使用。 - Brian Moeskau
其实,我发现我需要使用getResource()来访问我的模板文件——改变了代码,尝试导出为jar文件,现在它运行得非常好!我可能会选择这种方式,感谢提供的信息。 - Brian Moeskau
如果你想从类路径中获取内容,请使用getResource或getResourceAsStream。请注意,如果您想使用Java Web Start,则这是必需的步骤。 - Thorbjørn Ravn Andersen

0
Eclipse不会将classpath中的任何jar移动到项目的bin文件夹中。 您需要将util jar复制到bin文件夹中。 如果您将其移动到bin文件夹的根目录下,则可能无需任何classpath条目,但这不是推荐的解决方案。 有关更好的覆盖范围,请参见@BalusC的答案

0

Eclipse默认情况下不会构建可执行的Java类。 不要问我为什么,但这可能与使用自己的tools.jar(在plugins/org.eclipse.core中的某个位置?)有关,以便Eclipse可以在没有JDK的情况下运行。

通常您可以转到项目的bin目录并执行以下操作:

java -cp . MyClass

但是如果你有外部的jar包,Eclipse会以另一种奇怪的方式在内部处理它们,所以你也需要添加它们。


0

请确保您的jar包commons-lang-2.4.jar在类路径中,且不重复。

我曾经将jar文件添加到我的类路径中,并且在我的类路径中有两个jar文件。在我删除其中一个后,程序运行顺畅了。


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