JDK-4289940 : Can't dispose InputContext while it's active
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 4_dev,4_fcs,1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_8,windows_nt
  • CPU: generic,x86
  • Submitted: 1999-11-10
  • Updated: 2002-04-19
  • Resolved: 2002-04-19
Related Reports
Relates :  
Relates :  
Description
I got a program where I can reliable reproduce the following error:

Exception during disposal:
java.lang.reflect.InvocationTargetException: java.lang.IllegalStateException: Can't dispose InputContext while it's active
        at sun.awt.im.InputContext.dispose(InputContext.java:541)
        at java.awt.Window$1$DisposeAction.run(Window.java:442)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:151)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:318)
        at java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:107)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:97)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:88)


This happens when using keyboard input, e.g., pressing the spacebar, in
an JOptionPane. Clicking on the button does not cause the problem.

I tried to write a simpler example to provoke the error bug has been
unable to do so. Drop by Cup02 3th floor, or send email to get the
testcase
rene.schmidt@eng 1999-11-10



###@###.### 2002-04-08
This problem can easily reproduce using Java3D and JDK1.4 plugin
inside IE. The whole JVM/plugin hangs when pressing the back
button inside browsers. Here is the stack trace we got,
it can be repduced by installing Java3D v1.3 beta1 , go
the the programs/examples/index.html pages and try
the example one by one.

java.lang.IllegalStateException: Can't dispose InputContext while it's active	
at sun.awt.im.InputContext.dispose(InputContext.java:596)	
at java.awt.Window$1$DisposeAction.run(Window.java:524)	
at java.awt.Window.dispose(Window.java:534)	
at sun.plugin.viewer.frame.IExplorerEmbeddedFrame.windowClosing(Unknown Source)	
at java.awt.AWTEventMulticaster.windowClosing(AWTEventMulticaster.java:287)	
at java.awt.AWTEventMulticaster.windowClosing(AWTEventMulticaster.java:287)	
at java.awt.Window.processWindowEvent(Window.java:1083)	
at java.awt.Window.processEvent(Window.java:1042)	
at java.awt.Component.dispatchEventImpl(Component.java:3526)
at java.awt.Container.dispatchEventImpl(Container.java:1437)	
at java.awt.Window.dispatchEventImpl(Window.java:1566)	
at java.awt.Component.dispatchEvent(Component.java:3367)	
at java.awt.EventQueue.dispatchEvent(EventQueue.java:445)	
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:144)	
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)	
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)


Comments
EVALUATION Cannot reproduce problem on 'O' build rene.schmidt@eng 1999-11-15 Recent JDC comments imply that the bug is still reproducible on 1.3.x and the latest Merlin beta. Reopening this bug report for further investigation. ###@###.### 2001-12-17 I finally reproduced this problem with ###@###.###'s procedure. In the problem case, before I hit 'ESC' key, the input focus belongs to the 'A Makefile That Builds Anything' radio button. After I hit the 'ESC' key, no removeNotify() call for that radio button is issued. InputContext expects a removeNotify() for that radio button before its InputContext.dispose() is issued. That's the reason InputContext throws the IllegalStateException. I tentatively commented out a line of code in InputContext, where the IllegalStateException is thrown, not to throw the exception in sun.awt.im.InputContext.dispose() as follows: public void dispose() { if (currentClientComponent != null) { // throw new IllegalStateException("Can't dispose InputContext while it's active"); } Then, I got a NullPointerException shown below in AWT: Tue Apr 16 11:55:14 PDT 2002: java.lang.NullPointerException: <no message> java.lang.NullPointerException at java.awt.Component.requestFocusHelper(Component.java:6092) at java.awt.Component.requestFocusInWindow(Component.java:6033) at javax.swing.JComponent.requestFocusInWindow(JComponent.java:1142) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:284) at java.awt.Component.dispatchEventImpl(Component.java:3468) at java.awt.Container.dispatchEventImpl(Container.java:1582) at java.awt.Window.dispatchEventImpl(Window.java:1585) at java.awt.Component.dispatchEvent(Component.java:3439) at java.awt.EventQueue.dispatchEvent(EventQueue.java:448) at java.awt.SequencedEvent.dispatch(SequencedEvent.java:91) [catch] at java.awt.EventQueue.dispatchEvent(EventQueue.java:446) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136) at java.awt.EventDispatchThread.run(EventDispatchThread.java:99) This makes me me think that the focus handling in this case is something wrong. Transferring this bug to AWT team for further investigation. ###@###.### 2002-04-16 Commit to fix in mantis (hang). ###@###.### 2002-04-18 Name: rpR10076 Date: 04/19/2002 ###@###.### The exception (actually, both IllegalArgumentException and NPE referenced by Naoto) only happens in the following situation: a component that had focus at the moment of destruction of toplevel container (Frame, Window, Dialog) is removed from that container but has non-null peer at the moment when the toplevel container tries to dispose its InputContext. We consider such situation incorrect, and that's why exceptions are thrown. It is, however, difficult to achieve such situation (a component with non-null peer not contained in any toplevel). Based on Kelvin Chung's explanations (see comments section) and my investigation of Forte code, I think that all manifestations of this exceptions are produced by incorrect overriding of Container's removeNotify() method. The idea is that Container.removeNotify() calls removeNotify() for all its children, and that's where the connection between Window's InputContext and current focused component is broken. I'd say that if one wants to override removeNotify(), calling super.removeNotify() is obligatory, and doing so in the beginning of overriding method is desirable. Perhaps we'll need to clarify the JavaDoc on how to override this method correctly. In case of Forte, the JRadioButton has com.sun.forte.st.ipe.mfgen.MakefileTypePanel as its parent. This class extends JPanel, and overrides removeNotify() method in the following manner: public void removeNotify() { } There is no call to super.removeNotify() at all, and this is clearly a bug in client code. There are at least two more places in Forte code where removeNotify() is overridden without call to super.removeNotify() : org/netbeans/modules/java/ui/wizard/MemberListPanel.java org/netbeans/modules/java/wizard/IndexableExplorerList.java These two are also likely to cause the same exception. I suggest to close this report out as not a bug, and in the future, recommend all users who face this exception to check their code for removeNotify() implementations. ====================================================================== An additional problem was found relating to this issue, and a new bug was filed: 4867453. ###@###.### 2003-05-21 Name: rpR10076 Date: 07/18/2003 Yes, the exception occurs not only if you override removeNotify(), but also if you disable key events and/or remove key listeners after the component was shown and processed some key events. Right now for a workaround try not to do that after component was shown and processed some key events, and the problem will be dealth with under bugid 4867453. ======================================================================
11-06-2004

WORK AROUND "I ... recommend all users who face this exception to check their code for removeNotify() implementations." - fine, so please put this information in the detail message of the exception! To someone who runs across this exception, it is completely mystifying. You have no idea where to start debugging it. It would be helpful to mention the JDC bug # in the detail message and suggest that removeNotify() implementations be checked for calls to super, as the most probable cause of the exception. Also please do update the removeNotify() Javadoc to clearly require calls to super from all subclasses. Ditto addNotify() of course. Java, unlike e.g. CLOS, does not permit you to enforce such a contract programmatically very easily, so you have to resort to documentation. One thing which could *really* help is to use assertions. In Component, keep a package-private static Set<Component> of components for which removeNotify is being called. (A boolean might be enough, if removeNotify calls never nest nor overlap.) With assertions off, leave it null. With them on, (1) add to the impl of Component.removeNotify() a line to remove Component.this from the set; (2) every non-super caller of removeNotify in java.awt.* (is it called from anywhere else?) should (when assertions are on) first add the target Component to the set, then call removeNotify on it, then assert that the Component is no longer in the set. The effect will be that if any component in any user code fails to call super during removeNotify, an assertion failure will occur quickly if assertions are enabled on java.awt.*. This would greatly help diagnose the problem and get code cleaned up quickly. I have successfully used this trick in the NetBeans APIs: http://www.netbeans.org/source/browse/openide/src/org/openide/util/SharedClassObject.java.diff?r1=1.44&r2=1.44.2.1 Tue Nov 05 10:21:23 MST 2002 jg97958
11-06-2004