为什么我得到一个NoClassDefFoundError在Java?
-
09-06-2019 - |
题
我得到一个 NoClassDefFoundError
当我运行我Java应用程序。什么是通常的原因?
解决方案
这是造成时,有一类文件,该文件代码取决于它是本在编制时间,但没有发现在运行时间。看看差异在生成时间和运行类路径.
其他提示
虽然这是可能的,这是由于一类路径之间的不匹配的编写时间和运行时,它不一定是真实的。
重要的是要保持两个或三个不同的例外情况直在我们头在这种情况下:
java.lang.ClassNotFoundException
这种异常表示这类没有被发现的类路径。这表明,我们是试图负荷类定义,和这类不存在类路径。java.lang.NoClassDefFoundError
这一例外表示JVM看,在其内部的类定义的数据结构定义的一类,并没有找到它。这是不是说这不可能从这类路径。通常这表明我们以前试图载有类类路径,但由于某种原因失败-现在我们正在试图使用类再次(并因此需要加载它,因为它无法最后一次),但我们甚至不要试着装载它,因为我们未能装载之前(和合理的怀疑,我们将再次失败).早先的失败可能是一个ClassNotFoundException或ExceptionInInitializerError(指示中的失败静初始化框)或任何其他问题。这一点是,一个NoClassDefFoundError不一定是一类路径问题。
这里是代码说明 java.lang.NoClassDefFoundError
.请看看 Jared的答案 对于详细的解释。
NoClassDefFoundErrorDemo.java
public class NoClassDefFoundErrorDemo {
public static void main(String[] args) {
try {
// The following line would throw ExceptionInInitializerError
SimpleCalculator calculator1 = new SimpleCalculator();
} catch (Throwable t) {
System.out.println(t);
}
// The following line would cause NoClassDefFoundError
SimpleCalculator calculator2 = new SimpleCalculator();
}
}
SimpleCalculator.java
public class SimpleCalculator {
static int undefined = 1 / 0;
}
我们发现,有时候,我得到一个NoClassDefFound错误代码时,编制一个不兼容的版本的这类发现在运行时间。具体实例我记得是apache轴线图书馆。实际上有2版在我运行类路径,它挑选出的日期和不相容的版本并不是正确的,造成NoClassDefFound错误。这是在命令行程序,我在那里使用了类似的命令。
set classpath=%classpath%;axis.jar
我能得到它捡起适当的版本通过使用:
set classpath=axis.jar;%classpath%;
NoClassDefFoundError在Java
定义:
Java虚拟机是不是能找到某一特定类别在运行时,它是可以在汇编的时间。
如果一类是在编制时间,但不提供java类路径期间,运行时间。
实例:
- 这类不在类路径,也没有确定拍摄的方式知道但是很多时候你可以来看看打印系统。getproperty("java。类路径"),它将打印类路径从那里,你至少可以获得一个想法的实际运行类路径。
一个简单的例子NoClassDefFoundError是类属于一个失踪的罐子文件或罐子里是不是加入类路径或有时罐子的名称已经改变了一个人喜欢在我的情况下,我的一位同事已经改变了tibco.jar 入tibco_v3.jar 和程序是没有java。郎。NoClassDefFoundError我想知道什么是错误的。
只是试试运行与明确的-类路径选择的类路径你认为会的工作,如果它的工作然后这是一个肯定的短迹象表明有人为压倒一切的java类路径。
- 权限问题上的罐子文件也可能导致NoClassDefFoundError。
- 错字在XML结构还可能导致NoClassDefFoundError。
- 当你的编制类其定义是在一个软件包,并不存在相同的封装在装样的情况下JApplet它将引发NoClassDefFoundError。
可能的解决方案:
- 该课不提供Java类路径。
- 如果你的工作在于J2EE环境的可见度类在多个类装入器也可能导致java。郎。NoClassDefFoundError,请参见例子及方案部分详细讨论。
- 检查java。郎。ExceptionInInitializerError在你的记录文件。NoClassDefFoundError由于失败的静态初始化是很常见的。
- 因为NoClassDefFoundError是一个子类。郎。LinkageError它也可以进来,如果它的一个依赖性等原库可能不适用。
- 任何启动脚本是压倒一切类路径的环境变量。
- 你可能会运行程序使用罐子的命令和类是不是定义中的清单文件的类路径的属性。
资源:
这是的 最好的解决方案 我发现为止。
假设我们有一个包裹叫 org.mypackage
含有类:
- 案(主要类)
- SupportClass
- UtilClass
和文件限定这包存储物理下的目录 D:\myprogram
(Windows)或 /home/user/myprogram
(on Linux)。
当我们调用Java,我们指定的名称用来运行: org.mypackage.HelloWorld
.然而,我们也必须告诉Java在哪里找到的文件和目录确定我们的包裹。所以启动的程序,我们必须使用以下命令:
我得到NoClassFoundError当类装运行时级的加载程序无法访问的课程已经载入通过java rootloader.因为不同类机是在不同的安全域(根据java)jvm不会允许课程已经载入通过的rootloader须解决在运行时装载地址的空间。
运行程序与'java javaagent:tracer.jar [java ARGS]'
它产生出示的装载类,并加载程序env,载的类。这是非常有用的追踪为什么一类无法得到解决。
// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5
import java.lang.instrument.*;
import java.security.*;
// manifest.mf
// Premain-Class: ClassLoadTracer
// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
// java -javaagent:tracer.jar [...]
public class ClassLoadTracer
{
public static void premain(String agentArgs, Instrumentation inst)
{
final java.io.PrintStream out = System.out;
inst.addTransformer(new ClassFileTransformer() {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);
// dump stack trace of the thread loading class
Thread.dumpStack();
// we just want the original .class bytes to be loaded!
// we are not instrumenting it...
return null;
}
});
}
}
阅读这尤其是如果你看到 NoClassDefFoundErrors
在单位测试...
一个有趣的案例中,你会看到很多 NoClassDefFoundErrors
是时候你:
throw
一个RuntimeException
在static
框类的Example
- 拦截它(或者如果它只是没关系等它被抛在一个 测试情况)
- 尝试创建一个此类的实例
Example
static class Example {
static {
thisThrowsRuntimeException();
}
}
static class OuterClazz {
OuterClazz() {
try {
new Example();
} catch (Throwable ignored) { //simulating catching RuntimeException from static block
// DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
}
new Example(); //this throws NoClassDefFoundError
}
}
NoClassDefError
会被扔伴随着 ExceptionInInitializerError
从静态块 RuntimeException
.
这是特别重要的情况下当你看到 NoClassDefFoundErrors
在你 单元测试.
在你的"共享" static
框执行之间的试验,但始 ExceptionInInitializerError
将只是在一个测试案例。第一一个使用有问题 Example
类。其他试验的情况下使用 Example
类将只是扔 NoClassDefFoundErrors
.
以防你有所产生的代码(电磁场,等等。) 可以有太多的静态initialisers其消耗所有堆空间。
见堆溢出问题 如何增加Java堆尺寸?.
技术以下帮助了我很多次:
System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());
在TheNoDefFoundClass类,可能是"失去"由于偏好旧的版本相同的图书馆使用的程序。这种最常发生的情况下,当客户机软件,正在部署到一个占主导地位的容器,装备有自己类装入器和吨的古老版本的最受欢迎库。
我一定是我的问题通过禁止preDexLibraries所有模块:
dexOptions {
preDexLibraries false
...
NoClassDefFoundError
也可能发生时 静 初始化程序试图载资源束,是不是在运行时,例如一个属性文件,受影响的类尝试从 META-INF
目录,但是不存在。如果你没赶上 NoClassDefFoundError
, 有时你将不能够看到全部跟踪;为了克服这个,你可以暂时使用 catch
条款 Throwable
:
try {
// Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}
如果有人来这里是因为 java.lang.NoClassDefFoundError: org/apache/log4j/Logger
错误的,在我的情况下,它产生,因为我使用log4j2(但是我没有加入的所有文件,用它来),以及一些依存图书馆使用log4j1.解决办法是添加Log4j1.x桥:罐子 log4j-1.2-api-<version>.jar
带log4j2.更多信息在log4j2 移徙.
两种不同的结账的副本相同的项目
在我的情况下,问题是蚀未能区分两个不同的副本的同一个项目。我有一个锁上的干线(SVN版本控制),而另一个工作中的一个分支的时间。我试过了一项改变工作副本作为一个JUnit测试情况,其中包括提取私人内流是一个公共类对其自身并同时将其工作,我打开其他项目的副本,看看周围,在其他一些代码的一部分,需要改变。在某些时候, NoClassDefFoundError
弹出抱怨,私人内流是不存在;双击堆跟踪给我带来的源文件中的错误的项目副本。
关闭该干的副本项目和运行测试的情况下再次得到了摆脱的问题。
这种错误可能造成的未经检查的 Java version 要求。
在我的情况下,我能够解决这一错误,而建筑高档案的开放源项目,通过交换从Java9Java8使用 SDKMAN!.
sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu
然后做一个干净的安装,如下所述。
当使用 行家 作为你的建立工具,它有时是有益的--和通常可喜的,做 干净的 "安装",建立 与测试的残疾人.
mvn clean install -DskipTests
现在 的一切 已建成和安装,你可以继续运行测试。
mvn test
我NoClassDefFound错误的时候我没有出口一类"订购和出口"项Java建立道路的我的项目。确保选中的"以及出口"标签的任何相关性添加到项目的建立的道路。看看 日食警告:XXXXXXXXXXX.jar 不会出口或出版。运行时ClassNotFoundExceptions可能的结果.
Java是无法找到类在运行时间。一类是在家项目ArtClient从一个不同的工作区。所以我进口ArtClient我蚀的项目。我的两个项目使用ArtClient作为依赖。我改变图书馆参考项目参考用于这些人(建立的道路-->配置建立的路径)。
问题消失。
我有同样的问题,我的股票对许多小时。
我找到了解决办法。在我的情况下,有静态定义的方法因这一点。JVM不能创建的另一个目的,课。
例如,
private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
我得到这个消息后,去除两个文件从SRC库,并且当我把他们带回我一直看到这种错误信息。
我的解决方案是:重新启动蚀。从那以后我还没有看到这消息再次:-)
确保这个比赛 module:app
和 module:lib
:
android {
compileSdkVersion 23
buildToolsVersion '22.0.1'
packagingOptions {
}
defaultConfig {
minSdkVersion 17
targetSdkVersion 23
versionCode 11
versionName "2.1"
}