NetBeans' HintsController 和 EventQueue

发布于 2024-12-28 20:19:47 字数 5175 浏览 4 评论 0原文

我们正在构建一个基于 Netbeans 平台的应用程序,其中一部分是我们使用的特定语言的编辑器。

我们有以下类来突出显示语法中的错误:

class SyntaxErrorsHighlightingTask extends org.netbeans.modules.parsing.spi.ParserResultTask {

public SyntaxErrorsHighlightingTask () {
}

@Override
public void run (org.netbeans.modules.parsing.spi.Parser.Result result, org.netbeans.modules.parsing.spi.SchedulerEvent event) {
    try {
        final javax.swing.text.Document document = result.getSnapshot().getSource ().getDocument(false);
        final List<ErrorDescription> errors = new ArrayList<ErrorDescription> ();
        // finds errors on the document and add them to 'errors' list
        }

        /***
        OFFENDING CODE GOES HERE
        ***/

    } catch (javax.swing.text.BadLocationException ex1) {
        org.openide.util.Exceptions.printStackTrace (ex1);
    } catch (org.netbeans.modules.parsing.spi.ParseException ex1) {
        Exceptions.printStackTrace (ex1);
    }
}

@Override
public int getPriority () {
    return 100;
}

@Override
public Class<? extends Scheduler> getSchedulerClass () {
    return Scheduler.EDITOR_SENSITIVE_TASK_SCHEDULER;
}

@Override
public void cancel () {
}

}

引发异常的违规代码是这样的:

org.netbeans.spi.editor.hints.HintsController.setErrors (document, "testsequence", errors);

根据搜索结果,将其更改为以下内容:

SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                     System.err.println("is EDT? " + SwingUtilities.isEventDispatchThread());
                     HintsController.setErrors (document, "testsequence", errors);
                }
           });

以下是在编辑:

is EDT? true
SEVERE [org.openide.util.RequestProcessor]: Error in RequestProcessor org.netbeans.spi.editor.hints.HintsController$1
java.lang.IllegalStateException: Must be run in EQ
    at org.netbeans.editor.Annotations.addAnnotation(Annotations.java:195)
    at org.netbeans.modules.editor.NbEditorDocument.addAnnotation(NbEditorDocument.java:251)
    at org.openide.text.NbDocument.addAnnotation(NbDocument.java:504)
    at org.netbeans.modules.editor.hints.AnnotationHolder$NbDocumentAttacher.attachAnnotation(AnnotationHolder.java:235)
    at org.netbeans.modules.editor.hints.AnnotationHolder.attachAnnotation(AnnotationHolder.java:208)
    at org.netbeans.modules.editor.hints.AnnotationHolder.updateAnnotationOnLine(AnnotationHolder.java:674)
    at org.netbeans.modules.editor.hints.AnnotationHolder.setErrorDescriptionsImpl(AnnotationHolder.java:899)
    at org.netbeans.modules.editor.hints.AnnotationHolder.access$1300(AnnotationHolder.java:113)
    at org.netbeans.modules.editor.hints.AnnotationHolder$4.run(AnnotationHolder.java:812)
    at org.netbeans.editor.BaseDocument.render(BaseDocument.java:1409)
    at org.netbeans.modules.editor.hints.AnnotationHolder.setErrorDescriptions(AnnotationHolder.java:809)
    at org.netbeans.modules.editor.hints.HintsControllerImpl.setErrorsImpl(HintsControllerImpl.java:111)
    at org.netbeans.modules.editor.hints.HintsControllerImpl.setErrors(HintsControllerImpl.java:93)
    at org.netbeans.spi.editor.hints.HintsController$1.run(HintsController.java:79)
    at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1424)
    at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1968)
Caused: org.openide.util.RequestProcessor$SlowItem: task failed due to
    at org.openide.util.RequestProcessor.post(RequestProcessor.java:425)
    at org.netbeans.spi.editor.hints.HintsController.setErrors(HintsController.java:77)
    at com.#.#.#.editor.parser.SyntaxErrorsHighlightingTask$1.run(SyntaxErrorsHighlightingTask.java:74)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
    at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:148)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
[catch] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

发生的情况是,对 HintsController 的调用是在 EDT(EventDispatch Thread)中进行的。但是,Annotations.addAnnotation() 正在另一个线程中运行 - 有时在“系统剪贴板同步器”线程中,有时在“非活动 RequestProcessor”线程中。由于它检查是否在 EDT 上运行,因此它总是抛出 IllegalStateException。

我不是使用 Netbeans 平台的专家,而且我对公司的这个特定应用程序还很陌生 - 所以我可能会遗漏一些非常明显的东西。谷歌并没有多大帮助。有人有什么建议吗?

We are building an application based on the Netbeans Platform, and one part of it is an editor for a specific language we use.

We have the following class to highlight errors in the syntax:

class SyntaxErrorsHighlightingTask extends org.netbeans.modules.parsing.spi.ParserResultTask {

public SyntaxErrorsHighlightingTask () {
}

@Override
public void run (org.netbeans.modules.parsing.spi.Parser.Result result, org.netbeans.modules.parsing.spi.SchedulerEvent event) {
    try {
        final javax.swing.text.Document document = result.getSnapshot().getSource ().getDocument(false);
        final List<ErrorDescription> errors = new ArrayList<ErrorDescription> ();
        // finds errors on the document and add them to 'errors' list
        }

        /***
        OFFENDING CODE GOES HERE
        ***/

    } catch (javax.swing.text.BadLocationException ex1) {
        org.openide.util.Exceptions.printStackTrace (ex1);
    } catch (org.netbeans.modules.parsing.spi.ParseException ex1) {
        Exceptions.printStackTrace (ex1);
    }
}

@Override
public int getPriority () {
    return 100;
}

@Override
public Class<? extends Scheduler> getSchedulerClass () {
    return Scheduler.EDITOR_SENSITIVE_TASK_SCHEDULER;
}

@Override
public void cancel () {
}

}

The offending code, that throws an exception, is this:

org.netbeans.spi.editor.hints.HintsController.setErrors (document, "testsequence", errors);

Based on searching results, it was changed to the following:

SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                     System.err.println("is EDT? " + SwingUtilities.isEventDispatchThread());
                     HintsController.setErrors (document, "testsequence", errors);
                }
           });

The following is what happens when a syntax error is introduced in the editor:

is EDT? true
SEVERE [org.openide.util.RequestProcessor]: Error in RequestProcessor org.netbeans.spi.editor.hints.HintsController$1
java.lang.IllegalStateException: Must be run in EQ
    at org.netbeans.editor.Annotations.addAnnotation(Annotations.java:195)
    at org.netbeans.modules.editor.NbEditorDocument.addAnnotation(NbEditorDocument.java:251)
    at org.openide.text.NbDocument.addAnnotation(NbDocument.java:504)
    at org.netbeans.modules.editor.hints.AnnotationHolder$NbDocumentAttacher.attachAnnotation(AnnotationHolder.java:235)
    at org.netbeans.modules.editor.hints.AnnotationHolder.attachAnnotation(AnnotationHolder.java:208)
    at org.netbeans.modules.editor.hints.AnnotationHolder.updateAnnotationOnLine(AnnotationHolder.java:674)
    at org.netbeans.modules.editor.hints.AnnotationHolder.setErrorDescriptionsImpl(AnnotationHolder.java:899)
    at org.netbeans.modules.editor.hints.AnnotationHolder.access$1300(AnnotationHolder.java:113)
    at org.netbeans.modules.editor.hints.AnnotationHolder$4.run(AnnotationHolder.java:812)
    at org.netbeans.editor.BaseDocument.render(BaseDocument.java:1409)
    at org.netbeans.modules.editor.hints.AnnotationHolder.setErrorDescriptions(AnnotationHolder.java:809)
    at org.netbeans.modules.editor.hints.HintsControllerImpl.setErrorsImpl(HintsControllerImpl.java:111)
    at org.netbeans.modules.editor.hints.HintsControllerImpl.setErrors(HintsControllerImpl.java:93)
    at org.netbeans.spi.editor.hints.HintsController$1.run(HintsController.java:79)
    at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1424)
    at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1968)
Caused: org.openide.util.RequestProcessor$SlowItem: task failed due to
    at org.openide.util.RequestProcessor.post(RequestProcessor.java:425)
    at org.netbeans.spi.editor.hints.HintsController.setErrors(HintsController.java:77)
    at com.#.#.#.editor.parser.SyntaxErrorsHighlightingTask$1.run(SyntaxErrorsHighlightingTask.java:74)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
    at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:148)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
[catch] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

What happens is, the call is to HintsController is being made in the EDT (EventDispatch Thread). However, Annotations.addAnnotation() is being run in another thread - sometimes in the "System clipboard synchronizer" thread, sometimes in the "Inactive RequestProcessor" thread. Since it checks if its being run on the EDT, it always throws an IllegalStateException.

I'm no expert in using the Netbeans Platform, and I'm pretty new to this specific application on the company - so I might be missing something really obvious. Google didn't help much. Anyone has any advice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡看悲欢离合 2025-01-04 20:19:48

事实证明,这根本不是代码的问题。

正如 NetBeans-dev 列表中指出的那样:

HintsController.setErrors 可以从任何线程调用 - 它使用它的
自己的工作线程,并在必要时重新调度到 AWT 线程。

在 AWT 线程中调用 Annotations.addAnnotation 的要求有
很久以前就被删除了:
http://hg.netbeans.org/main-silver/rev/db82e4e0fbcc

同一变更集还删除了 AWT 线程的自动重新调度
在 NbDocument.addAnnotation 中。所以看来你正在使用的构建
具有变更集的第二部分,但没有第一部分 (...)

在仔细检查 maven 的 pom.xml 文件后,我意识到应用程序正在加载较新版本的库,而模块正在加载旧版本,因此它会运行错误的代码。关于该问题的相关问题此处

Turns out, it was not a problem with the code after all.

As pointed on the NetBeans-dev list:

HintsController.setErrors can be called from any thread - it uses its
own worker thread, and reschedules to AWT thread when necessary.

The requirement to invoke Annotations.addAnnotation in AWT thread has
been removed quite some time ago by:
http://hg.netbeans.org/main-silver/rev/db82e4e0fbcc

The same changeset also removed automatic rescheduling into AWT thread
in NbDocument.addAnnotation. So it seems that the build you are using
has the second part of the changeset, but not the first part (...)

After a careful review of maven's pom.xml files, I realized that the application was loading newer versions of the libs while the module was loading older versions, so it would run the wrong code. Related SO question about that here.

昔梦 2025-01-04 20:19:48

也许您应该尝试使用如下方法更新您的错误:

private void updateError(javax.swing.text.Document document, List<ErrorDescription> errors) {
    if(javax.swing.SwingUtilities.isEventDispatchThread()) {
        HintsController.setErrors (document, "testsequence", errors);
    }
    else {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                 HintsController.setErrors (document, "testsequence", errors);
            }
       });
    }    
}

Maybe you should try to update your errors with a method like this one :

private void updateError(javax.swing.text.Document document, List<ErrorDescription> errors) {
    if(javax.swing.SwingUtilities.isEventDispatchThread()) {
        HintsController.setErrors (document, "testsequence", errors);
    }
    else {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                 HintsController.setErrors (document, "testsequence", errors);
            }
       });
    }    
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文