java NoClassDefFoundError 的可能原因
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12606477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Possible reasons for NoClassDefFoundError
提问by questions
I'm getting the following NoClassDefFoundError
, which is weird because the class is already present in the library jar.
我得到以下内容NoClassDefFoundError
,这很奇怪,因为该类已经存在于库 jar 中。
Exception in thread "main" java.lang.NoClassDefFoundError: abc/test/Test.java
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:795)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:144)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:382)
at java.net.URLClassLoader.access0(URLClassLoader.java:75)
at java.net.URLClassLoader.run(URLClassLoader.java:294)
at java.net.URLClassLoader.run(URLClassLoader.java:288)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:795)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:144)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:382)
at java.net.URLClassLoader.access0(URLClassLoader.java:75)
at java.net.URLClassLoader.run(URLClassLoader.java:294)
at java.net.URLClassLoader.run(URLClassLoader.java:288)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:432)
Caused by: java.lang.ClassNotFoundException: abc.test.Test
at java.net.URLClassLoader.run(URLClassLoader.java:299)
at java.net.URLClassLoader.run(URLClassLoader.java:288)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 25 more
This looks like its not able to find the same class which is causing the exception.
I have also included the library path in ant build.xml
, which can be verified below.
这看起来像它无法找到导致异常的同一个类。我还在 ant 中包含了库路径build.xml
,可以在下面进行验证。
<property name="deps" value="${lib}/abclib/abclib-test.jar"/>
<target name="dist" depends="compile">
<manifest file="${dist}/MANIFEST.MF">
<attribute name="Main-Class" value="xyz.test.TestConfiguration" />
<attribute name="Class-Path" value="${deps}"/>
</manifest>
<jar jarfile="${dist}/abc.jar" basedir="${build}/" manifest="${dist}/MANIFEST.MF" />
</target>
I'm lost, can someone at least guide me where should I look or what I might be doing wrong?
我迷路了,至少有人可以指导我应该看哪里或我可能做错了什么吗?
Also, can someone throw light, "Exception" and "Caused by". I'm not quite getting how are they two related.
另外,有人可以抛出“异常”和“由”引起的光。我不太明白他们两个有什么关系。
回答by davidfmatheson
There's a really good explanation of the difference between NoClassDefFoundError
and ClassNotFoundException
in another SO entry:
对于另一个SO 条目之间NoClassDefFoundError
和之间的区别,有一个非常好的解释:ClassNotFoundException
does not mean that the ... class is not in the CLASSPATH. Infact its quite the opposite. It means that the class ... was found by the ClassLoader however when trying to load the class, it ran into an error reading the class definition. This typically happens when the class in question has static blocks or members which use a Class that's not found by the ClassLoader. So to find the culprit, view the source of the class in question ... and look for code using static blocks or static members.
并不意味着 ... 类不在 CLASSPATH 中。事实上,它恰恰相反。这意味着类 ... 被 ClassLoader 找到,但是在尝试加载类时,它在读取类定义时遇到了错误。这通常发生在所讨论的类具有静态块或使用类加载器未找到的类的成员时。因此,要找到罪魁祸首,请查看相关类的源代码……并查找使用静态块或静态成员的代码。
You need to look at the code for Test.java and figure out what it imports and make sure those classes are on the classpath. You could post the code of Test.java if you need help tracking the classes down.
您需要查看 Test.java 的代码并找出它导入的内容并确保这些类位于类路径中。如果您需要帮助跟踪类,您可以发布 Test.java 的代码。
回答by felvhage
Initializing a static field with a functionmay cause a hard to unveil NoClassDefFoundError
用函数初始化静态字段可能会导致难以揭开NoClassDefFoundError
Example: when you do something like this:
示例:当您执行以下操作时:
public class SomePanel extends Panel {
static int CALC_VALUE = ValueCalcUtils.calcValue();
...
...where
...在哪里
ValueCalcUtils.calcValue()
... may throw an Exception.
... 可能会抛出异常。
Then, when the Exception is thrown, this will happen:
然后,当抛出异常时,会发生这种情况:
- There will be one single Error indicating on the actual Problem(that
ValueCalcUtils.calcValue()
has thrown an Exception for some reason) - Every subsequent try to create an instance of
SomePanel
will throw a (misleading)NoClassDefFoundError
forSomePanel
.
- 将有一个错误指示实际问题(
ValueCalcUtils.calcValue()
由于某种原因引发了异常) - 随后每次尝试创建 的实例
SomePanel
都会抛出(误导性的)NoClassDefFoundError
forSomePanel
。
This happens because the JVM will remember that SomePanel
could not be initialized the first time he tried to create the class definition, and therefore does "not have a class definition" (NoClassDefFoundError
) for SomePanel
when asked again.
发生这种情况是因为 JVM 会记住SomePanel
在他第一次尝试创建类定义时无法初始化,因此在再次询问时没有“没有类定义”( NoClassDefFoundError
) SomePanel
。
In a Wicket/Tomcat situation ...
在 Wicket/Tomcat 情况下......
I've had this exact Problem with a Wicket-Application on a Tomcat-Webserver. The Problem was, that the static Utils-Method relied on WicketApplication.get()
.
我在 Tomcat-Webserver 上的 Wicket-Application 遇到了这个确切的问题。问题是,静态 Utils-Method 依赖于WicketApplication.get()
.
Where this would work in most cases, it would lead to the described Problem when the Tomcat tried to restore old Sessions from the SessionStore on startup. Sometimes the Sessions contained serialized Instances of the Panel in Question. When initializing the Panel-Class there was an Exception because the WicketApplicationdid not yet exist on Tomcat startup.
Later on we had alot of confusing NoClassDefFoundError
s for the Panel in our Application-Logs, without apparent reason.
在大多数情况下这会起作用,当 Tomcat 尝试在启动时从 SessionStore 恢复旧会话时,它会导致所描述的问题。有时,会话包含相关小组的序列化实例。初始化 Panel-Class 时出现异常,因为WicketApplication在 Tomcat 启动时尚不存在。后来我们NoClassDefFoundError
在我们的应用程序日志中有很多令人困惑的面板,没有明显的原因。
We finally found the single appearance of the "root Error" in the tomcat-stderror.logfile, since it was the tomcat throwing the initial error on startup.
我们终于在 tomcat-stderror.log文件中找到了“root Error”的单一出现,因为它是 tomcat 在启动时抛出初始错误。
Hope this helps someone.
希望这可以帮助某人。
回答by Rohit Jain
There is a difference between ClassNotFoundException
and NoClassDefFoundError
..
ClassNotFoundException
和NoClassDefFoundError
..之间有区别
While first
one denote that the class
you are using is not in your classpath
虽然first
一个表示class
您正在使用的不在您的classpath
Second
one denotes that, the class
you are using is in turn using another class
that is not in your classpath..
Second
one 表示,class
您正在使用的反过来使用另一个class
不在您的类路径中的..
So, the problem is not that you don't have your class in classpath.. But the problem is, the classes
on which your class is dependent is not in your classpath..
Now, you need to check what all classes
, does your class
(the one used currently in your code) depends upon..
所以,问题不在于你的类路径中没有你的类..但问题是,classes
你的类所依赖的不在你的类路径中..现在,你需要检查classes
你的class
(当前在您的代码中使用的一个)取决于..
回答by Ian Roberts
The Class-Path
entry in MANIFEST.MF
has a specific format, in particular the entries in the classpath must be relative URIs (relative to the location of the JAR that contains the manifest). Ant has a manifestclasspath
taskto help in constructing suitable classpaths.
的Class-Path
在条目MANIFEST.MF
具有特定的格式,特别是在类路径中的条目必须相对URI(相对于包含清单中的JAR的位置)。Ant 有一项manifestclasspath
任务来帮助构建合适的类路径。
<target name="dist" depends="compile">
<property name="jar.location" location="${dist}/mcon.jar"/>
<manifestclasspath property="manifest.class.path" jarfile="${jar.location}">
<classpath>
<pathelement location="${deps}" />
</classpath>
</manifestclasspath>
<manifest file="${dist}/MANIFEST.MF">
<attribute name="Main-Class" value="xyz.test.TestConfiguration" />
<attribute name="Class-Path" value="${manifest.class.path}"/>
</manifest>
<jar jarfile="${jar.location}" basedir="${build}/" manifest="${dist}/MANIFEST.MF" />
</target>
This should set up the Class-Path
with the correct format (presumably something like ../lib/abclib/abclib-test.jar
in your example)
这应该Class-Path
使用正确的格式设置(大概类似于../lib/abclib/abclib-test.jar
您的示例)
回答by Arnab Biswas
NoClassDefFoundError means that the class was present during the compilation and not during the run time execution. So, as suggested by others you need to understand the classpath that is being used during the run time and not during compile time.
NoClassDefFoundError 意味着该类在编译期间存在,而不是在运行时执行期间存在。因此,正如其他人所建议的那样,您需要了解在运行时而不是在编译时使用的类路径。
回答by Roman C
NoClassDefFoundError
thrown as a result that your classloader cannot load a definition of a class. Make sure the correct path of the class that is on the classpath is given. Check for the library is in classpath. Modify you MANIFEST.MF
so that a library exist in Class-Path
. Run java with the command line -cp switch to denote a library on the classpath.
NoClassDefFoundError
抛出的结果是您的类加载器无法加载类的定义。确保给出了类路径上的类的正确路径。检查库是否在类路径中。修改您MANIFEST.MF
以便库存在于Class-Path
. 使用命令行 -cp 开关运行 java 以表示类路径上的库。