假冒建设银行网站,各大网站的名字大全,郑州做网站的联系方式,比亚迪唐100使用了哪些网络营销方式本文是我们的NoClassDefFoundError故障排除系列的第2部分。 看一下第1部分 。 它将重点介绍最简单的NoClassDefFoundError问题类型。 本文对于Java初学者来说是理想的选择#xff0c;我强烈建议您自己编译并运行示例Java程序。 今后将使用以下书写格式#xff0c;并为您提供我强烈建议您自己编译并运行示例Java程序。 今后将使用以下书写格式并为您提供 –问题案例的描述和NoClassDefFoundError的类型 –示例Java程序“模拟”问题情况 – ClassLoader链视图 –建议和解决策略 NoClassDefFoundError问题案例1 –缺少JAR文件 我们将介绍的第一个问题案例与Java程序包装和/或类路径问题有关。 典型的Java程序可以包含一个或多个在编译时创建的JAR文件。 当您忘记添加包含Java或Java EE应用程序引用的Java类的JAR文件时通常会观察到NoClassDefFoundError。 一旦您分析了Java异常并缺少Java类名通常就不难解决这种类型的问题。 示例Java程序 以下简单的Java程序按以下方式拆分 –主Java程序NoClassDefFoundErrorSimulator –调用者Java类CallerClassA –引用Java类ReferencingClassA –用于ClassLoader和日志记录相关设施的util类JavaEETrainingUtil 这个程序很简单它试图创建一个新实例并执行一个Java类CallerClassA的方法该方法引用了ReferencingClassA类。 它将演示一个简单的类路径问题如何触发NoClassDefFoundError。 该程序还在类加载时显示当前类加载器链的详细信息以帮助您跟踪此过程。 当处理更大的类加载器链时这对于将来和更复杂的问题案例特别有用。 package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** NoClassDefFoundErrorTraining1* author Pierre-Hugues Charbonneau**/
public class NoClassDefFoundErrorSimulator {/*** param args*/public static void main(String[] args) {System.out.println(java.lang.NoClassDefFoundError Simulator - Training 1);System.out.println(Author: Pierre-Hugues Charbonneau);System.out.println(http://javaeesupportpatterns.blogspot.com);// Print current Classloader contextSystem.out.println(\nCurrent ClassLoader chain: JavaEETrainingUtil.getCurrentClassloaderDetail());// 1. Create a new instance of CallerClassACallerClassA caller new CallerClassA();// 2. Execute method of the callercaller.doSomething();System.out.println(done!);}
}package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** CallerClassA* author Pierre-Hugues Charbonneau**/
public class CallerClassA {private final static String CLAZZ CallerClassA.class.getName();static {System.out.println(Classloading of CLAZZ in progress...JavaEETrainingUtil.getCurrentClassloaderDetail());}public CallerClassA() {System.out.println(Creating a new instance of CallerClassA.class.getName()...);}public void doSomething() {// Create a new instance of ReferencingClassAReferencingClassA referencingClass new ReferencingClassA(); }
}package org.ph.javaee.training1;import org.ph.javaee.training.util.JavaEETrainingUtil;/*** ReferencingClassA* author Pierre-Hugues Charbonneau**/
public class ReferencingClassA {private final static String CLAZZ ReferencingClassA.class.getName();static {System.out.println(Classloading of CLAZZ in progress...JavaEETrainingUtil.getCurrentClassloaderDetail());}public ReferencingClassA() {System.out.println(Creating a new instance of ReferencingClassA.class.getName()...);}public void doSomething() {//nothing to do...}
}package org.ph.javaee.training.util;import java.util.Stack;
import java.lang.ClassLoader;/*** JavaEETrainingUtil* author Pierre-Hugues Charbonneau**/
public class JavaEETrainingUtil {/*** getCurrentClassloaderDetail* return*/public static String getCurrentClassloaderDetail() {StringBuffer classLoaderDetail new StringBuffer(); StackClassLoader classLoaderStack new StackClassLoader();ClassLoader currentClassLoader Thread.currentThread().getContextClassLoader();classLoaderDetail.append(\n-----------------------------------------------------------------\n);// Build a Stack of the current ClassLoader chainwhile (currentClassLoader ! null) {classLoaderStack.push(currentClassLoader);currentClassLoader currentClassLoader.getParent();}// Print ClassLoader parent chainwhile(classLoaderStack.size() 0) {ClassLoader classLoader classLoaderStack.pop();// Print current classLoaderDetail.append(classLoader);if (classLoaderStack.size() 0) {classLoaderDetail.append(\n--- delegation ---\n); } else {classLoaderDetail.append( **Current ClassLoader**);}}classLoaderDetail.append(\n-----------------------------------------------------------------\n);return classLoaderDetail.toString();}
} 问题重现 为了重现该问题我们将简单地“自愿”从包含引用Java类ReferencingClassA的类路径中省略其中一个JAR文件。 Java程序的包装如下 – MainProgram.jar包含NoClassDefFoundErrorSimulator.class和JavaEETrainingUtil.class -CallerClassA.jar包含CallerClassA.class – ReferencingClassA.jar包含ReferencingClassA.class 现在让我们按原样运行程序 建议和解决策略 ##基准正常执行 ..\binjava -classpath CallerClassA.jar;ReferencingClassA.jar;MainProgram.jar org.ph.javaee.training1.NoClassDefFoundErrorSimulatorjava.lang.NoClassDefFoundError Simulator - Training 1
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.comCurrent ClassLoader chain:
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Classloading of org.ph.javaee.training1.CallerClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Creating a new instance of org.ph.javaee.training1.CallerClassA...
Classloading of org.ph.javaee.training1.ReferencingClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader214c4ac9 **Current ClassLoader**
-----------------------------------------------------------------Creating a new instance of org.ph.javaee.training1.ReferencingClassA...
done! 发生了什么 删除包含ReferencingClassA的ReferencingClassA.jar确实阻止了当前类加载器在运行时定位此引用Java类从而导致ClassNotFoundException和NoClassDefFoundError。 如果您从Java启动类路径中或Java EE相关应用程序的EAR / WAR中省略JAR文件这将是典型的异常。 ClassLoader视图 现在让我们回顾一下ClassLoader链以便您可以正确地了解这种问题情况。 从Java程序输出日志记录中可以看到找到了以下Java ClassLoader Classloading of org.ph.javaee.training1.CallerClassA in progress...
-----------------------------------------------------------------
sun.misc.Launcher$ExtClassLoader17c1e333
--- delegation ---
sun.misc.Launcher$AppClassLoader214c4ac9 **Current ClassLoader**
----------------------------------------------------------------- **请注意Java引导类加载器负责加载核心JDK类并以本机代码编写** ## sun.misc.Launcher $ AppClassLoader 这是系统类加载器负责加载在启动时指定的Java类路径中找到的应用程序代码。 ## sun.misc.Launcher $ ExtClassLoader 这是扩展类加载器负责将代码加载到扩展目录java_home / lib / ext或java.ext.dirs系统属性指定的任何其他目录中。 从Java程序日志输出中可以看到扩展类加载器是系统类加载器的实际超级父级。 我们的示例Java程序是在系统类加载器级别加载的。 请注意对于这种问题情况该类加载器链非常简单因为我们此时尚未创建子类加载器。 这将在以后的文章中介绍。 建议和解决策略 现在在下面找到我对NoClassDefFoundError问题案例1的建议和解决策略 –检查java.lang.NoClassDefFoundError错误并确定缺少的Java类 -在编译/构建环境中验证并找到丢失的Java类 -确定缺少的Java类是来自应用程序代码第三方API还是Java EE容器本身。 验证预期在哪里找到丢失的JAR文件 –找到后验证您的运行时环境Java类路径是否存在任何拼写错误或丢失的JAR文件 –如果问题是由Java EE应用程序触发的请执行与上述相同的步骤但请验证EAR / WAR文件的包装是否缺少JAR和其他库文件依赖项如MANIFEST。 请随时发表任何问题或评论。 第3部分将很快上市。 参考 java.lang.NoClassDefFoundError如何解决–第2部分来自我们的JCG合作伙伴 Pierre-Hugues Charbonneau位于Java EE支持模式和Java教程博客。 翻译自: https://www.javacodegeeks.com/2012/06/this-article-is-part-2-of-our.html