我刚刚开始一个大型的新项目,其中包含的menuBar = new MenuBar();
MenuBar 行被打包在 javafx.scene.control 中。没有错误,但是当它在运行时遇到这条线时,我得到了
线程“AppKit 线程”中的异常 java.lang.NoClassDefFoundError:无法初始化类 javafx.scene.control.MenuBar
Google 建议我的构建路径和运行时路径之间存在差异。我不确定的是如何实际判断构建路径和运行时路径是什么,尽管我认为我是对的。
构建路径:我去
Properties -> Java Build Path
看看JRE System Library [Java SE 8 [1.8.0_77]]
那里。我进一步确认它包含jfxrt.jar
. 它还在构建时没有检测到任何错误,因此我可以假设它正在工作。
运行时路径:我去
Run As -> Run Configurations... -> Classpath
并查看JRE System Library [Java SE 8 [1.8.0_77]]
Bootstrap Entries 中列出的内容。我似乎无法扩展它并确认它包含相关的 jar。
我在运行时类路径中遗漏了什么吗?
编辑:我发现了另一种症状,或对此的细微差别。menuBar = new MenuBar() 包含在扩展 FX Stage 类的对象的构造函数中。通过单击启动器上的按钮来初始化构造函数。当我第一次点击它时,我得到一个Exception in thread "AppKit Thread" java.lang.ExceptionInInitializerError
. 我第二次单击它是出现 NoClassDefFoundError 时。这意味着什么吗?
编辑 2:仍在试图解决这个问题。我可能已将其缩小到 Style 的问题。我真的不知道这意味着什么,但跟踪可能会有所帮助:
Caused by: java.lang.NullPointerException
at com.sun.javafx.css.StyleManager.getURL(StyleManager.java:867)
at com.sun.javafx.css.StyleManager.loadStylesheetUnPrivileged(StyleManager.java:1057)
at com.sun.javafx.css.StyleManager.loadStylesheet(StyleManager.java:917)
at com.sun.javafx.css.StyleManager._setDefaultUserAgentStylesheet(StyleManager.java:1377)
at com.sun.javafx.css.StyleManager.setUserAgentStylesheets(StyleManager.java:1209)
at com.sun.javafx.application.PlatformImpl.lambda$_setPlatformUserAgentStylesheet$182(PlatformImpl.java:698)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl._setPlatformUserAgentStylesheet(PlatformImpl.java:697)
at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:548)
at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:512)
at javafx.scene.control.Control.<clinit>(Control.java:87)
... 6 more
我不知道如何跟进这些...6 更多,但我可以手动跟踪到 JFX MenuBar 类以在 MenuBar 构造函数中找到它:getStyleClass().setAll(DEFAULT_STYLE_CLASS);
似乎是发生这种情况的一个很好的候选者。我不确定如何继续,因为它在 .class 文件本身中。希望这会有所帮助。
编辑 3:我得到的建议是创建一个新工作区,从 SVN 检查项目,然后重新开始。当时的想法是,工作空间可能以某种方式被破坏了。没有改变; 出现了完全相同的错误。我在这里没有想法了。
编辑 4:(感谢格式化,Itachi!)这是我可以显示的内容,被遮盖了:
package _______;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import ____.FooMenu;
import ____.FooMenuItem;
import ____.FooUtil;
import ____.FooVBox;
import ____.FooStates;
public class FooStageWithMenu extends FooStage
{
private MenuBar menuBar;
private FooMenu fileMenu;
private FooVBox root;
public FooStageWithMenu(FooStates setting, Image icon)
{
super();
set(setting, icon);
root = new FooVBox();
menuBar = new MenuBar(); //This line is where it fails
root.addNode(menuBar);
/*...*/
}
/*...*/
}
其他一些想法:
- 我正在 OSX 上开发,我在项目中与之交谈的每个人都在使用 Windows。这个问题是否存在特定于操作系统的根源?
- 我们想消除库问题的可能性,所以我安装了最新版本,现在运行 JDK 1.8.0_102,问题仍然存在。
- 是否有可能即使在最新的 JDK
jfxrt.jar
中,我们各自库中的 s 之间也存在一些差异? - 特定错误的性质(参见上面的编辑 2)。似乎有人试图通过检索 URL 来访问样式表,但它要么无法访问该样式表,要么无法获取 URL,或者其他什么。似乎没有什么
NullPointerException
可以帮助我缩小范围。我确实探索了我的jfxrt.jar
,发现在 JavaFX 类似乎正在搜索的路径中,.css 文件确实存在并且看起来完整且没有损坏。
编辑 5:所以我很确定没有人在读这个,但我确实找到了一个大线索,与这个版本和以前版本之间的区别有关。我认为我不需要详细说明,但是通过在启动器类中注释掉一行来“解决”这个问题。我们有两个启动器类,其中一个扩展了另一个。扩展类的构造函数只是super(); new JFXPanel();
如果我注释掉第二行,它不会立即出现任何明显的问题。这可能是在 Mac 上打破它的线路,而它在 Windows 中运行良好。我不知道这意味着什么,我也不知道为什么我分享的原始失败是由此引起的。但是这个更改只是在测试分支中进行的,所以考虑到临时和有限的性质,我们可能不需要对这个问题进行适当的修复。我只是想分享更新,以防它帮助其他人。