gpt4 book ai didi

java - 触发事件时自发的 NullPointerExceptions

转载 作者:太空狗 更新时间:2023-10-29 22:58:15 26 4
gpt4 key购买 nike

我目前正在结合 LWJGL 库制作 JavaFX 关卡编辑器,以实现 OpenGL 功能,从而使用多线程。

然而,我的问题是,有时当我触发 JavaFX 事件时(当我按下按钮/键等时),我会自发地遇到 java.lang.NullPointerException。我似乎无法弄清楚错误发生的确切时间模式,并且由于某些奇怪的原因,堆栈跟踪不会向我提供异常发生的位置。我所知道的是,当我以某种方式与 JavaFX 应用程序线程交互时,它就会发生。

然而,当它确实发生时,它不仅将它打印到控制台一次然后崩溃。发生的事情是应用程序不断地一遍又一遍地打印出错误消息,直到我强制关闭应用程序。发生错误时,我似乎无法再触发某些特定事件。

这是我收到的自发重复错误消息:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes(Unknown Source)
at javafx.scene.Scene$ScenePulseListener.pulse(Unknown Source)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Unknown Source)
at com.sun.javafx.tk.Toolkit$$Lambda$153/452428720.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Unknown Source)
at com.sun.javafx.tk.Toolkit.firePulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$400(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$42/424424770.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/12064136.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

我猜想和“同步节点”有关。由于我正在使用多线程处理以使用 OpenGL 运行渲染循环,这可能与这种情况有关。我也在使用 Java8 中的 Lambda 表达式,显然正如它在错误日志中所说的那样,它也与它们有关。

我不期望有人能准确回答我的问题是什么,我做错了什么,因为我没有提供任何代码(因为我的项目太大,我不知道异常在哪里发生)。但是,我有几个一般性问题:

  1. 这个错误日志是什么意思?

  2. 这可能是什么原因造成的?

  3. 为什么它不向我提供异常发生位置的任何信息?

我通过将 Eclipse 中的 JRE 从 JRE 安装切换到 JDK 提供的 jar,设法从堆栈跟踪中获取行号。这使我能够从编译的 API 中获取行号,例如 JavaFX 本身。

这是新的错误日志:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes(Scene.java:2289)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2419)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:314)
at com.sun.javafx.tk.Toolkit$$Lambda$153/478814140.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:313)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:340)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:525)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:505)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$400(QuantumToolkit.java:334)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$42/1940618951.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/640174177.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

我的错误出在 JavaFX 类中,也可能在我的 lambda 表达式中的某个地方,因为唯一仍然显示 (Unknown Source) 的地方也是它也显示“lambda”的地方。也许堆栈跟踪无法在 lambda 中显示行号?

无论如何,这是返回 NullPointerException 的代码行:

if (node.getScene() == Scene.this)

这是在 JavaFX Scene 类中

最佳答案

不是答案,只是解决一个非常相似的问题的建议 - 一个 Swing 问题。

为了避免任何猜测,我们应该查看源代码——解决“未知来源”部分。您提供的堆栈跟踪缺少行号。这是因为,标准 JRE 是在没有任何调试信息的情况下编译的。曾经,我相信在 Sun 时代,人们可以下载一个针对开发人员的单独发行版,其中包含所有调试符号。这使得除了具有确切的行号之外,还可以在 JDK 代码中设置断点。

我们可以从那里开始调查问题。

如果没有带有调试符号的 JRE,您可以随时尝试编译自己的!我曾经成功地编译了 JDK 发行版附带的“src.zip”文件。虽然它不是独立的!缺少几个部分,一些 Linux 特定类等。JDK 本身的 javac 文件有问题 - 它一直用完内存。幸运的是,Eclipse 的 javac 编译器可以处理大代码库和部分编译类。

然后,我在 Bootstrap 类路径中使用生成的 jar(使用调试符号编译的 src.zip)运行我的程序。通常,不允许修改“java.”和“sun.”包内的任何内容。使用 Bootstrap 类路径,您可以。

现在,回到您的特定问题:JavaFX 和 OpenGL 都通过所谓的“线程限制”解决了多线程问题。这意味着,一切都是强制单线程的。您的问题可能源于 javaFx 和 OpenGL 都有各自独立的线程!我敢打赌,您在 JavaFX 的 EDT 之外进行了一些交互。但是,这只是一个牵强附会的假设。尝试获取源代码行,我们可以从那里继续。

当我需要调试信息时,我正在关注这里的答案:debug jdk source can't watch variable what it is

但是,所有的工作可能都不需要!我刚刚了解到,您可以将源文件本身附加到引导类路径,如下所示:https://stackoverflow.com/a/10498425


更新,

因此,“节点”引用似乎为空(我怀疑“this”为空)。下一步将识别空节点并找到添加它的确切时间。我可能会在所有合理的“addNode”调用中放置一些断点(或打印输出语句)——来自您的程序。

从源代码(我快速浏览了 http://grepcode.com/file/repo1.maven.org/maven2/net.java.openjfx.backport/openjfx-78-backport/1.8.0-ea-b96.1/javafx/scene/Scene.java#2263)看来,“null”引用似乎来自“dirtyNodes”数组。

通常我最好的选择是,您从适当的线程外部间接调用调用 addToDirtyNodes ( http://grepcode.com/file/repo1.maven.org/maven2/net.java.openjfx.backport/openjfx-78-backport/1.8.0-ea-b96.1/javafx/scene/Scene.java#503 )。令我惊讶的是,第一行检查它是否是从正确的那一行调用的:

Toolkit.getToolkit().checkFxUserThread();

您是否碰巧在程序输出中看到“Not on FX application thread; currentThread =”这一行?

希望这不是 JavaFX 本身的错误。

关于java - 触发事件时自发的 NullPointerExceptions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29457693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com