Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Orphaned event (EventQueue.dummyRunnable) in an eventQueue will break waitForIdle.

未关闭
#243 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
30/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
停滞
技术栈
java

调研方向

先从 BasicRobot.waitForIdle 及其对 windowMonitor.allEventQueues() 的处理入手,然后检查所提供复现程序周围 java.awt.EventQueue 的 push/pop 行为。使用隐藏的 JFrame 和自定义 EventQueue 运行示例;当 waitForIdle 能及时返回,且不会将孤立队列或 dummyRunnable 视为待处理工作时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

I've seen a sporadic failure where waitForIdle gets into a state where it times out after 10 seconds. The application is actually idle when this happens. This causes a lot of grief for us because it makes all the test run at a snails pace (20 minutes instead of 20 seconds).

2 important conditions for this failure:

  1. install a custom eventQueue via Toolkit.getDefaultToolkit().getSystemEventQueue().push()
  2. create and hide a Window first. (this is a splash screen in our real app).

After a lot of debugging by adding logs to BasicRobot waitForIdle, I manage to catch it where the custom event queue was empty, but it was waiting for a java.awt.EventQueue to drain. It contained an InvocationEvent with this runnable. "runnable=java.awt.EventQueue$1@2d1630f3". Looking into that lead me to the first anonymous class in EventQueue, which is the member variable "dummyRunnable". That dummyRunnable is used in push/pop to wake up the EDT.

I theorized that if the EDT was already awake when the new Queue was pushed, then that event could be left.

That didn't fail initially when I only had 1 window and tried the push from within an InvokeAndWait. I then expanded the test to create a window, hide it, push a new queue and then wait.

That reproduces the failure. Simple test case below. I think that the first queue (for the hidden window?) is really dead? maybe it should be removed from the "windowMonitor.allEventQueues()" in BasicRobot? I got this far, and now I'm at a loss as to how to proceed.

package ajs.eq.fail;

import java.awt.EventQueue;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.assertj.swing.core.BasicRobot;

public class AjsEqFail {

    private final static EventQueue myQueue = new EventQueue() {
        
    };
    public static void main(String[] args) {
        BasicRobot r = (BasicRobot) BasicRobot.robotWithCurrentAwtHierarchy();
        r.settings().simpleWaitForIdle(false);
        final JFrame f = new JFrame();
        f.setBounds(10,10,300,300);
        f.setVisible(true);
        r.waitForIdle();
        System.out.println("waited");
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("Hi3");
                        }
                    });
                    System.out.println("Hi1");
                    f.setVisible(false);
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(myQueue);
                    JFrame f2 = new JFrame();
                    f2.setVisible(true);
                    f2.setBounds(10,10,300,300);
                    System.out.println("Hi2");
                }
            });
        } catch (InterruptedException ex) {
            Logger.getLogger(AjsEqFail.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(AjsEqFail.class.getName()).log(Level.SEVERE, null, ex);
        }
        r.waitForIdle(); //<-------------this times eventually (30 seconds?) but should be immediate.
        System.out.println("waited2");
    }
    
}

主要语言
Java
星标
121
派生
52
PR 合并指标
30 天内没有已合并 PR

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

assertj/assertj-swing 的其他 Issue

查看 assertj/assertj-swing 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。