Java JFace FontRegistry上的NoClassDefFoundError
当我启动SWT应用程序(通过Eclipse启动配置文件)时,我会收到以下堆栈跟踪:Java JFace FontRegistry上的NoClassDefFoundError,java,eclipse,swt,Java,Eclipse,Swt,当我启动SWT应用程序(通过Eclipse启动配置文件)时,我会收到以下堆栈跟踪: Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jface/resource/FontRegistry at org.eclipse.jface.resource.JFaceResources.getFontRegistry(JFaceResources.java:338) at org.eclipse.
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jface/resource/FontRegistry
at org.eclipse.jface.resource.JFaceResources.getFontRegistry(JFaceResources.java:338)
at org.eclipse.jface.window.Window.close(Window.java:313)
at org.eclipse.jface.dialogs.Dialog.close(Dialog.java:971)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.close(ProgressMonitorDialog.java:348)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.finishedRun(ProgressMonitorDialog.java:582)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:498)
at com.blah.si.workflow.SWTApplication.main(SWTApplication.java:135)
现在,让这件事变得奇怪的是:
ClassNotFoundException
。该类位于类路径上。如果我将源代码附加到jar,我可以调试到getFontRegistry方法中。该方法将成功执行多次,最后在第338行抛出NoClassDefFoundError
。第337行是“if variable==null”语句,用于检查静态变量是否已初始化。如果第338行尚未初始化,则它正在初始化。第一次通过时,null检查失败,并执行初始化。在随后通过该方法的过程中,将通过null检查,从而返回已初始化的静态值。在最后一次通过(失败的一次)时,空检查再次失败(即使静态变量已经初始化),并且当它尝试重新初始化静态变量时,抛出NoClassDefFoundError
。以下是相关的源代码(从第336行开始,注意fontRegistry是一个私有静态变量,不在其他地方设置):NoClassDefFoundError
指示:
- 类
由org.eclipse.jface.resource.FontRegistry
类加载器找到
- 但是如果不触发错误,就无法加载,比如使用
类加载器未找到的
类的静态块或成员李>
getFontRegistry()
函数使用的是静态变量fontRegistry:
/**
* The JFace font registry; <code>null</code> until lazily initialized or
* explicitly set.
*/
private static FontRegistry fontRegistry = null;
因此,它提出了一个问题:为什么突然又会认为a是null
因为不知怎么的
如果一个字段被声明为静态的,那么不管最终创建了多少个类实例(可能为零),该字段只存在一个化身。静态字段(有时称为类变量)在初始化类时具体化(§12.4)
因此,无论类的实例在任何时候是否存在,只要类本身被加载,字段就会存在
如果这是一个eclipse插件,那么它可能与这个 以下是新用户的典型场景:
您正在编写扩展插件XYZ的插件。
要使其编译,您可以从Java构建路径属性页或通过编辑.classpath文件将插件XYZ的JAR文件的引用添加到项目的构建路径中。
启动运行时工作台时,会报告以下意外错误:
java.lang.NoClassDefFoundError:XYZ.SomeClass
不要开始查看运行时工作台启动配置中的插件和片段选项卡。该选项卡仅影响运行时工作台使用的插件,以及它们是从工作区还是从Eclipse安装目录加载的 相反,开始查看插件清单。
编辑plugin.xml文件,并确保XYZ是必需的插件
然后,保存plugin.xml文件。
这将自动更新项目的生成路径 编写插件时,切勿手动编辑.classpath文件。
插件清单编辑器只覆盖您对其所做的任何更改。不是很文明,但这就是它的工作方式
听起来您缺少了一个包含依赖项的JAR文件,如2006年7月的这篇博文所述,作者: 当类加载器找不到报告的类时,将抛出一个
ClassNotFoundException
。这通常意味着
类路径中缺少该类
这也可能意味着所讨论的类正试图从另一个类加载,该类加载在父类ClassLoader
中,因此子类ClassLoader
中的类不可见。
在应用服务器等更复杂的环境中工作时,有时会出现这种情况(WebSphere因此类ClassLoader
问题而臭名昭著)
人们往往会混淆java.lang.NoClassDefFoundError
w
/**
* The JFace font registry; <code>null</code> until lazily initialized or
* explicitly set.
*/
private static FontRegistry fontRegistry = null;
java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory
private static SomeClass foo = new SomeClass();
public void run(boolean fork, boolean cancelable,
IRunnableWithProgress runnable) throws InvocationTargetException,
InterruptedException {
setCancelable(cancelable);
try {
aboutToRun();
// Let the progress monitor know if they need to update in UI Thread
progressMonitor.forked = fork;
ModalContext.run(runnable, fork, getProgressMonitor(), getShell()
.getDisplay());
} finally {
finishedRun(); // this is line 498
}
}
try
{
final Class clazz;
final ClassLoader loader;
clazz = Class.forName("org/eclipse/jface/resource/FontRegistry");
loader = clazz.getClassLoader();
System.out.println("The classloader at step 1 is: " + loader);
}
catch(final Throwable ex)
{
ex.printStackTrace();
}
org.eclipse.core.commands_xxxxx.jar