如何解决java.lang.NoClassDefFoundError--第二部分
如何解决NoClassDefFoundError--第二部分
第一部分请看:http://vipcowrie.iteye.com/blog/1561291
本文面向的是JAVA初学者,建议你们自己编译和运行例子程序。
本文包含了NoClassDefFoundError的原因分析和例子程序,并且给出了建议的处理策略。
NoClassDefFoundError 问题原因1:缺少jar包
首先最常见的原因是classpath的配置问题。例子程序:
本例子程序尝试创建一个新的CallerClassA实例,然后执行他的一个方法,此方法引用了类ReferencingClassA,本例子演示了classpath问题导致的NoClassDefFoundError ,本例子还打印了当前的classloader chain的情况,以便进一步的分析。这个打印信息对你以后分析此类问题也很有帮助的:
程序
public class NoClassDefFoundErrorSimulator { public static void main(String[] args) { System.out .println("java.lang.NoClassDefFoundError Simulator"); // Print current Classloader context System.out.println("\nCurrent ClassLoader chain: " + ClassloaderUtil.getCurrentClassloaderDetail()); // 1. Create a new instance of CallerClassA CallerClassA caller = new CallerClassA(); // 2. Execute method of the caller caller.doSomething(); System.out.println("done!"); }}
public class CallerClassA { private final static String CLAZZ = CallerClassA.class.getName(); static { System.out.println("Classloading of " + CLAZZ + " in progress..." + ClassloaderUtil.getCurrentClassloaderDetail()); } public CallerClassA() { System.out.println("Creating a new instance of " + CallerClassA.class.getName() + "..."); } public void doSomething() { // Create a new instance of ReferencingClassA ReferencingClassA referencingClass = new ReferencingClassA(); }}
public class ReferencingClassA { private final static String CLAZZ = ReferencingClassA.class.getName(); static { System.out.println("Classloading of " + CLAZZ + " in progress..." + ClassloaderUtil.getCurrentClassloaderDetail()); } public ReferencingClassA() { System.out.println("Creating a new instance of " + ReferencingClassA.class.getName() + "..."); Maps.newHashMap(); } public void doSomething() { // nothing to do... }}
public class ClassloaderUtil { public static String getCurrentClassloaderDetail() { StringBuffer classLoaderDetail = new StringBuffer(); Stack<ClassLoader> classLoaderStack = new Stack<ClassLoader>(); ClassLoader currentClassLoader = Thread.currentThread() .getContextClassLoader(); classLoaderDetail .append("\n-----------------------------\n"); // Build a Stack of the current ClassLoader chain while (currentClassLoader != null) { classLoaderStack.push(currentClassLoader); currentClassLoader = currentClassLoader.getParent(); } // Print ClassLoader parent chain while (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 -classpath .;../guava-12.0.jar NoClassDefFoundError.NoClassDefFoundErrorSimulatorjava.lang.NoClassDefFoundError SimulatorCurrent ClassLoader chain:-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Classloading of NoClassDefFoundError.CallerClassA in progress...-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Creating a new instance of NoClassDefFoundError.CallerClassA...Classloading of NoClassDefFoundError.ReferencingClassA in progress...-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Creating a new instance of NoClassDefFoundError.ReferencingClassA...done!
java -classpath . NoClassDefFoundError.NoCljava.lang.NoClassDefFoundError SimulatorCurrent ClassLoader chain:-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Classloading of NoClassDefFoundError.CallerClassA in progress...-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Creating a new instance of NoClassDefFoundError.CallerClassA...Classloading of NoClassDefFoundError.ReferencingClassA in progress...-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-----------------------------Creating a new instance of NoClassDefFoundError.ReferencingClassA...Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/collect/Maps at NoClassDefFoundError.ReferencingClassA.<init>(ReferencingClassA.java:28) at NoClassDefFoundError.CallerClassA.doSomething(CallerClassA.java:31) at NoClassDefFoundError.NoClassDefFoundErrorSimulator.main(NoClassDefFoundErrorSimulator.javCaused by: java.lang.ClassNotFoundException: com.google.common.collect.Maps at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ... 3 more
Classloading of NoClassDefFoundError.CallerClassA in progress...-----------------------------sun.misc.Launcher$ExtClassLoader@addbf1--- delegation ---sun.misc.Launcher$AppClassLoader@19821f **Current ClassLoader**-------------------------