JDK-6506617 : Keyboard-lock in swing program on Linux box
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt:i18n
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: solaris_2.5.1
  • CPU: x86
  • Submitted: 2006-12-20
  • Updated: 2017-01-26
  • Resolved: 2017-01-20
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
RHEL 4 - Linux 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux
Red Flag 5 - Linux 2.6.9-11.19AXsmp #1 SMP Fri Aug 5 05:28:32 EDT 2005 i686 i686 i386 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
gnome-desktop-2.8.0-5
kdebase-3.2.1-62AX.i386.  kdelibs-3.2.1-44AX.i386.


A DESCRIPTION OF THE PROBLEM :
Run some swing program, keyboard is locked after some opterations, then it don't respond any key event.

Here is a demo program, no multi-thread, no event-dispatching thread problem. It always can be reproduced on RHEL 4 and Red Flag 5.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program I post, follow the steps in "about":

1 - press Alt+N to navigate next, and don't release keys untill there are no more next page, then try Alt+B to navigate back and also don't release keys untill page 0, repeat Alt+N and Alt+B again and again, keyboard will be locked during navigating.

2 - press Alt+A in main window, it will popup an about dialog, then press down space key and don't release, the about dialog will be closed and opened again and again, keyboard will be locked sooner or later.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Keyboard should not be locked!

ACTUAL -
The keyboard focus is there, but it don't respond any key event in all component and window, except in JPasswordField.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class KeyLock extends JFrame {
  JPanel contentPanel = new JPanel();
  JPanel wizardToolPan = new JPanel();
  JButton btnBack = new JButton("Back");
  JButton btnNext = new JButton("Next");
  JButton btnAbout = new JButton("About");
  public static final String aboutMsg =
          "<html>  This program will help to find keyboard lock problems, two way to reproduce:<br><br>" +
          "1 - press Alt+N to navigate next, and don't release keys untill there are no more next page, <br>" +
          "then try Alt+B to navigate back and also don't release keys untill page 0,<br>" +
          "repeat Alt+N and Alt+B again and again, keyboard will be locked during navigating. <br><br>" +
          "2 - press Alt+A in main window, it will popup an about dialog,<br>" +
          "then press down space key and don't release, <br>" +
          "the about dialog will be closed and opened again and again,<br>" +
          "keyboard will be locked sooner or later." +
          "</html>";

  public KeyLock() {
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setTitle("Keyboard lock test");

    getContentPane().setLayout(new BorderLayout());
    btnBack.setMnemonic('B');
    btnBack.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        KeyLock.this.goBack(e);
      }
    });

    btnNext.setMnemonic('N');
    btnNext.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        KeyLock.this.goNext(e);
      }
    });

    btnAbout.setMnemonic('A');
    btnAbout.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(KeyLock.this, aboutMsg, "About", JOptionPane.INFORMATION_MESSAGE);
      }
    });

    contentPanel.setLayout(new BorderLayout());
    contentPanel.setPreferredSize(new Dimension(400, 250));
    contentPanel.setMinimumSize(new Dimension(400, 250));

    wizardToolPan.setLayout(new FlowLayout());
    wizardToolPan.add(btnBack);
    wizardToolPan.add(btnNext);
    wizardToolPan.add(btnAbout);

    this.getContentPane().add(contentPanel, java.awt.BorderLayout.CENTER);
    this.getContentPane().add(wizardToolPan, java.awt.BorderLayout.SOUTH);

    this.setSize(400, 300);
    this.createContentPanels();
    this.showCurrent();
  }

  private Vector<JPanel> slides = new Vector<JPanel>();
  private int current = 0;

  private void createContentPanels() {
    for (int j = 0; j < 20; ++j) {
      JPanel p = new JPanel(new FlowLayout());
      p.add(new JLabel("Page: " + j));
      p.add(new JTextField("Page: " + j + ", input something here", 20));
      p.add(new JTextField("Page: " + j + ", input something here", 20));
      p.add(new JTextField("Page: " + j + ", input something here", 20));
      p.add(new JLabel("Input something in password box:"));
      p.add(new JPasswordField(20));
      p.add(new JCheckBox("Try click here, focus will be here."));
      p.add(new JRadioButton("Try click here, focus will be here."));

      slides.add(p);
    }
  }

  public void showCurrent() {
    if (current < 0 || current >= slides.size())
      return;

    JPanel p = slides.get(current);
    this.contentPanel.add(p, java.awt.BorderLayout.CENTER);
    this.pack();

    Component[] comps = p.getComponents();
    if (comps.length > 0) {
      comps[0].requestFocus(); // try delete this line
    }
    this.repaint();
  }

  public void goNext(ActionEvent e) {
    if (current + 1 >= slides.size())
      return;
    this.contentPanel.remove(slides.get(current));
    current++;
    sleep(100);
    this.showCurrent();
  }

  public void goBack(ActionEvent e) {
    if (current <= 0)
      return;
    this.contentPanel.remove(slides.get(current));
    current--;
    sleep(100);
    this.showCurrent();
  }

  public static void sleep(int millis) {
    try {
      Thread.sleep(millis);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    KeyLock wizard = new KeyLock();
    wizard.setVisible(true);
  }
}

---------- END SOURCE ----------

Comments
Closing this as cannot reproduce as the issue is not reproducible with 9 ea.
20-01-2017

Checked this with 9 ea b152 and confirmed that the issue is not reproducible. (See attached screenshot).
20-01-2017

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

WORK AROUND Use "kinput2" as the im server, instead of "ibus".
06-01-2011

EVALUATION I changed the im server from ibus to kinput2 to see what happens (on Ubuntu 10.10). I could not reproduce the hang up with the kinput2 im server anymore. This does not necessarily mean something is wrong between Xlib<->IM Server communication, but more likely. Since there is a workaround (use kinput2 as the input methbod server), downgrading this to P3.
06-01-2011

EVALUATION I looked at the threads when this hang occured. Here are the dump (java side) for the relevant two threads (AWT-EventQueue-0 and AWT-XAWT): --- "AWT-EventQueue-0" prio=10 tid=0x0861b400 nid=0xf08 runnable [0x00a21000] java.lang.Thread.State: RUNNABLE at sun.awt.X11.XInputMethod.createXICNative(Native Method) at sun.awt.X11.XInputMethod.createXIC(XInputMethod.java:70) at sun.awt.X11InputMethod.activate(X11InputMethod.java:333) - locked <0xa9b377c8> (a sun.awt.X11.XInputMethod) at sun.awt.im.InputContext.activateInputMethod(InputContext.java:393) at sun.awt.im.InputContext.focusGained(InputContext.java:337) - locked <0xa9b37758> (a sun.awt.im.InputMethodContext) - locked <0xac3dfe00> (a java.awt.Component$AWTTreeLock) at sun.awt.im.InputContext.dispatchEvent(InputContext.java:244) at sun.awt.im.InputMethodContext.dispatchEvent(InputMethodContext.java:197) at java.awt.Component.dispatchEventImpl(Component.java:4725) at java.awt.Container.dispatchEventImpl(Container.java:2271) at java.awt.Component.dispatchEvent(Component.java:4619) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1908) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:928) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:560) at java.awt.Component.dispatchEventImpl(Component.java:4663) at java.awt.Container.dispatchEventImpl(Container.java:2271) at java.awt.Component.dispatchEvent(Component.java:4619) at sun.awt.SunToolkit$4.run(SunToolkit.java:618) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) at java.awt.EventQueue.dispatchEvent(EventQueue.java:660) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:121) at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182) at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:221) at java.security.AccessController.doPrivileged(Native Method) at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:219) at java.awt.Dialog.show(Dialog.java:1072) at java.awt.Component.show(Component.java:1629) at java.awt.Component.setVisible(Component.java:1581) at java.awt.Window.setVisible(Window.java:975) at java.awt.Dialog.setVisible(Dialog.java:1003) at AutoKeyLock$3$2.actionPerformed(AutoKeyLock.java:78) at javax.swing.Timer.fireActionPerformed(Timer.java:292) at javax.swing.Timer$DoPostEvent.run(Timer.java:224) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) at java.awt.EventQueue.dispatchEvent(EventQueue.java:660) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:121) at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182) at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:221) at java.security.AccessController.doPrivileged(Native Method) at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:219) at java.awt.Dialog.show(Dialog.java:1072) at java.awt.Component.show(Component.java:1629) at java.awt.Component.setVisible(Component.java:1581) at java.awt.Window.setVisible(Window.java:975) at java.awt.Dialog.setVisible(Dialog.java:1003) at AutoKeyLock$3$2.actionPerformed(AutoKeyLock.java:78) (and this pattern continues) --- "AWT-XAWT" daemon prio=10 tid=0x0818ec00 nid=0xeb3 waiting on condition [0x01404000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0xacbf7478> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197) at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214) at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290) at sun.awt.SunToolkit.awtLock(SunToolkit.java:274) at sun.awt.X11.XToolkit.run(XToolkit.java:607) at sun.awt.X11.XToolkit.run(XToolkit.java:589) at java.lang.Thread.run(Thread.java:732) --- Unlike what is stated in the Comments section, these two threads don't seem to have reentrant issues. "awtLock" effectively seems to arbitrate those Xlib calls. Now I looked at the native side call stack on "AWT-EventQueue-0" thread: ---(gdb) info stack #0 0x0012e416 in __kernel_vsyscall () #1 0x00223df6 in poll () from /lib/libc.so.6 #2 0x01337d90 in ?? () from /usr/lib/libxcb.so.1 #3 0x01339707 in xcb_wait_for_event () from /usr/lib/libxcb.so.1 #4 0x01236752 in wait_or_poll_for_event (dpy=0x8163a90, wait=<value optimized out>) at ../../src/xcb_io.c:145 #5 0x01236aa1 in process_responses (dpy=0x8140618, wait_for_first_event=<value optimized out>, current_error=0x0, current_request=0) at ../../src/xcb_io.c:173 #6 0x0123739b in _XReadEvents (dpy=0x8140618) at ../../src/xcb_io.c:279 #7 0x012159af in XIfEvent (dpy=0x8140618, event=0x1496f28, predicate=0x1264270 <_CheckCMEvent>, arg=0x8243a90 "L\373\060\001\270\367\027\bp\304$\b\030\006\024\b") at ../../src/IfEvent.c:69 #8 0x01264c77 in _XimXRead (im=0x8243a90, recv_buf=0x14970d8 "", buf_len=2048, ret_len=0x1496ffc) at ../../../../modules/im/ximcp/imTrX.c:468 #9 0x01263d80 in _XimReadData (im=<value optimized out>, len=<value optimized out>, buf=0x14970d8 "", buf_size=2048) at ../../../../modules/im/ximcp/imTransR.c:171 #10 0x01264144 in _XimRead (im=0x8243a90, len=0x14981de, buf=0x14970d8 "", buf_size=2048, predicate=0x124f9f0 <_XimCreateICCheck>, arg=0x0) at ../../../../modules/im/ximcp/imTransR.c:241 #11 0x01250c85 in _XimProtoCreateIC (xim=0x8243a90, arg=0x0) at ../../../../modules/im/ximcp/imDefIc.c:1537 #12 0x0123cbc9 in XCreateIC (im=0x8243a90) at ../../../src/xlibi18n/ICWrap.c:248 #13 0x010e7ab4 in createXIC (env=0x8192518, this=0x1498340, window=88080674) at ../../../src/solaris/native/sun/awt/awt_InputMethod.c:1149 #14 Java_sun_awt_X11_XInputMethod_createXICNative (env=0x8192518, this=0x1498340, window=88080674) at ../../../src/solaris/native/sun/awt/awt_InputMethod.c:1603 #15 0xb5ff70ad in ?? () --- Looking at the Xlib source for "_XimProtoCreateIC", it looks like the client code sends "XIM_CREATE_IC" to the server, then waits for its reply forever. Not sure the reason for it, though.
30-12-2010

WORK AROUND Restart ibus-daemon.
18-11-2010

EVALUATION The problem is intermittent to appear so I had to write a test which hangs in 100% with similar symptoms. See attach AutoKeyLock.java. The only thing is I can't reproduce the original "hard hang" that means that the keyboard don't work at all afterwards. That doesn't happen with original test as well as with newly created test in the same environment.
25-10-2010

EVALUATION XAWT code recieves the KeyRelease from native and forwards it into Java. That causes the JButton to trigger ActionEvent regardless of being blocked or not. At the same time on Windows a pressed key would generate WM_DOWN only. And WM_UP on the key release. There are no reliable way either to detect nor to disable autorepeat with X11 API. There is the XkbSetDetectableAutoRepeat(dp, detectable, supported_rtrn) but that feature is required to be supported by the WM. Mine doesn't so I even hadn't a chance to look if it works. By now I don't see how could we provide a native "feel" with Java "look" in this particular scenario. We can't ask users to issue "xset -r 65" to prevent SPACE autorepeat.
22-10-2010

EVALUATION Revisited with Ubuntu 10.04/xfce. There's already not SCIM but IBus. Setup is, (1) installation of the language support and ibus packages; (2) setting console locale to ja_JP.UTB-8 (3) export XMODIFIERS="@im=ibus" (4) starting ibus-daemon --xim (5) setting Japanese keyboard layout. In my xfce it's just setxkbmap -rules evdev -model pc105 -layout "jp" After starting KeyLock application with jdk7.b104, I was not able to lock the keyboard with Alt+N/Alt+B, however Alt+A and space did lock the keyboard immediately and very consistently. Not even once in a series of runs in this environment About popup popped twice. Without IM (English locale and layout, empty XMODIFIERS, stopped ibus-daemon) I could not reproduce the behavior. I cannot say I know the cause though.
26-08-2010

EVALUATION This may be a platform issue (cf. http://bugs.freedesktop.org/show_bug.cgi?id=7869). The description in the 'comment' section is very similar the investigation on freedesktop.org one.
14-08-2007

EVALUATION (tested on Solaris 10 sparc) I don't believe this is an input method issue, but rather AWT focus or dialog modality issue. Here are the reasonings for it: - I could reproduce the problem even if I pass 0 (NULL) for XFilterEvent() for the second issue. - When I try to reproduce the second issue (modal dialog open/close one), some space keys are actually dispatched to the shell window that started the test case, which means that modality is broken. Also, when the lock happens, I see a couple of the "About" dialogs shown at the same time. - It's harder to reproduce the problem in 'C' locale, however, if you run a lot of applications at the same time (e.g., running 5 instances of Java2Demo), I could reproduce it in 'C'. So I believe this is locale/inputmethod independent. Transferring to the AWT.
09-08-2007

EVALUATION The issue is seen in XToolkit. JDK5 and later versions all have the same problem. Currently, targeted to 7, then we'll plan to backport.
14-03-2007

EVALUATION Using RHEL4 with ja_JP.UTF-8 locale, KeyPress events were consumed by XFilterEvent when it's running with XToolkit (default); however, this is not a case with MToolkit. While XToolkit passes window argument when it calls XFilterEvent, MToolkit passes NULL. When NULL is passed, keylock problem does not happen. However if NULL is passe in XToolkit, input method gets disabled.
09-03-2007

WORK AROUND When the keybord lock occurs, the user can navigate with mouse click although this is not very accessible workaround.
07-03-2007