当我运行Java应用程序时,我得到了一个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;
}
其他回答
我也遇到了同样的问题,我的存货积压了好几个小时。
我找到了解决办法。在我的例子中,有一个静态方法因此而定义。JVM不能创建该类的另一个对象。
例如,
private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
下面是演示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;
}
下面的技巧帮助了我很多次:
System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());
其中nodeffoundclass是可能会“丢失”的类,这是由于您的程序使用相同库的旧版本的首选项。当客户端软件被部署到一个占主导地位的容器中,并配备了自己的类加载器和大量最流行的库的古老版本时,这种情况最常发生。
更新[https://www.infoq.com/articles/single-file-execution-java11/]:
在Java SE 11中,可以选择启动单个源代码文件 直接,不需要中间编译。为了方便大家, 所以像你这样的新手不需要运行javac + Java(当然, 让他们感到困惑)。
对此,我的解决方案是为缺失的特定类“利用”类路径内容。在我的情况下,我有2个依赖项,虽然我能够成功地编译使用javac…,我不能运行产生的类文件使用java…,因为BouncyCastle jar中的Dynamic类不能在运行时加载。
javac --classpath "ext/commons-io-2.11.0;ext/bc-fips-1.0.2.3" hello.java
因此在编译时和运行时,JVM知道在哪里获取Apache Commons和BouncyCastle依赖项,然而,当运行这个时,我得到了
Error: Unable to initialize main class hello
Caused by: java.lang.NoClassDefFoundError:
org/bouncycastle/jcajce/provider/BouncyCastleFipsProvider
因此,根据类路径,我在相同的位置手动创建了一个名为ext的新文件夹,然后在其中放置了BouncyCastle jar,以确保在运行时可以找到它。只要结果清单中指定了jar的位置,您就可以将jar相对于类文件或jar文件放置。注意,我只需要利用包含丢失类文件的一个jar。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap