Topic
  • 3 replies
  • Latest Post - ‏2013-01-08T12:02:28Z by slowhand
SystemAdmin
SystemAdmin
2606 Posts

Pinned topic IlvSwingControl.setFocus causes Eclipse to hang

‏2012-09-26T13:58:58Z |
Hi,

In our product, we use IlvSwingControl to embed ILog into views. We find that sometimes, when we click on a view / editor, the entire workbench will hang as Eclipse tries to set focus to the view that uses IlvSwingControl.

I took a stacktrace and here's what I found. When it hanged, on the main SWT UI thread, we attempt to set focus. Please note that because I am calling IlvSwingControl.setFocus and IlvSwingControl is a SWT widget, I must make this call on the UI thread.

As the control tries to request focus, eventually it calls IlvSWTUtil.invokeAndWait(...)
3XMTHREADINFO "P=343122:O=34:CT" J9VMThread:0x0000000013AC4500, j9thread_t:0x0000000013A6E5B0, java/lang/Thread:0x00002AAAAFFE8AB8, state:CW, prio=6
3XMTHREADINFO1 (native thread ID:0x627A, native priority:0x6, native policy:UNKNOWN)
3XMTHREADINFO2 (native stack address range from:0x0000000040894000, to:0x0000000041295000, size:0xA01000)
3XMTHREADINFO3 Java callstack:
4XESTACKTRACE at java/lang/Object.wait(Native Method)
4XESTACKTRACE at java/lang/Object.wait(Object.java:167(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue.invokeAndWait(EventQueue.java:1033(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvSWTUtil.invokeAndWait(Bytecode PC:16(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.a(Bytecode PC:9(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.k(Bytecode PC:56)
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.c(Bytecode PC:1)
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1$6.focusLost(Bytecode PC:4)
4XESTACKTRACE at org/eclipse/swt/widgets/TypedListener.handleEvent(TypedListener.java:143(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/EventTable.sendEvent(EventTable.java:84(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Widget.sendEvent(Widget.java:1258(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Widget.sendEvent(Widget.java:1274(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Widget.sendEvent(Widget.java(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.sendFocusEvent(Control.java:3392(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.gtk_event_after(Control.java:2760(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Widget.windowProc(Widget.java:1738(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.windowProc(Control.java:4796(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Display.windowProc(Display.java:4360(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/internal/gtk/OS._gtk_widget_grab_focus(Native Method)
4XESTACKTRACE at org/eclipse/swt/internal/gtk/OS.gtk_widget_grab_focus(OS.java:12693(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.forceFocus(Control.java:2170(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Composite.forceFocus(Composite.java:526(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.forceFocus(Control.java:2163(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Control.setFocus(Control.java:3760(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Composite.setFocus(Composite.java:1370(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/widgets/Composite.setFocus(Composite.java:1370(Compiled Code))
4XESTACKTRACE
While the SWT waits for the AWT event thread, this is what the AWT event thread is doing:
3XMTHREADINFO "AWT-EventQueue-0" J9VMThread:0x000000001AFE5100, j9thread_t:0x0000000019D8B530, java/lang/Thread:0x00002AAAB3B270F8, state:CW, prio=6
3XMTHREADINFO1 (native thread ID:0x7CFD, native priority:0x6, native policy:UNKNOWN)
3XMTHREADINFO2 (native stack address range from:0x0000000041E36000, to:0x0000000041E77000, size:0x41000)
3XMTHREADINFO3 Java callstack:
4XESTACKTRACE at java/lang/Object.wait(Native Method)
4XESTACKTRACE at java/lang/Object.wait(Object.java:167(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/internal/Lock.lock(Lock.java:28(Compiled Code))
4XESTACKTRACE at org/eclipse/swt/internal/gtk/OS.gdk_bitmap_create_from_data(OS.java:3464)
4XESTACKTRACE at org/eclipse/swt/graphics/Cursor.createCursor(Cursor.java:436)
4XESTACKTRACE at org/eclipse/swt/graphics/Cursor.<init>(Cursor.java:254(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvSWTCustomCursor.<init>(Bytecode PC:44)
4XESTACKTRACE at ilog/views/util/swt/internal/IlvSWTUtil.convertCursor(Bytecode PC:822(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.a(Bytecode PC:40(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.a(Bytecode PC:29(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1.a(Bytecode PC:29(Compiled Code))
4XESTACKTRACE at ilog/views/util/swt/internal/IlvEmbeddedFrameControlv1$21.run(Bytecode PC:29(Compiled Code))
4XESTACKTRACE at ilog/views/util/swing/IlvSwingUtil$3.run(Bytecode PC:29(Compiled Code))
4XESTACKTRACE at java/awt/event/InvocationEvent.dispatch(InvocationEvent.java:220(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue.dispatchEventImpl(EventQueue.java:650(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue.access$000(EventQueue.java(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue$1.run(EventQueue.java(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue$1.run(EventQueue.java(Compiled Code))
4XESTACKTRACE at java/security/AccessController.doPrivileged(AccessController.java:224)
4XESTACKTRACE at com/ibm/oti/security/CheckedAccessControlContext.securityCheck(CheckedAccessControlContext.java:30(Compiled Code))
4XESTACKTRACE at sun/misc/JavaSecurityAccessWrapper.doIntersectionPrivilege(JavaSecurityAccessWrapper.java(Compiled Code))
4XESTACKTRACE at java/awt/EventQueue.dispatchEvent(EventQueue.java:621(Compiled Code))
4XESTACKTRACE at java/awt/EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:280(Compiled Code))
4XESTACKTRACE at java/awt/EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:195)
4XESTACKTRACE at java/awt/EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:185)
4XESTACKTRACE at java/awt/EventDispatchThread.pumpEvents(EventDispatchThread.java:180)
4XESTACKTRACE at java/awt/EventDispatchThread.pumpEvents(EventDispatchThread.java:172)
4XESTACKTRACE at java/awt/EventDispatchThread.run(EventDispatchThread.java:133)

As you can see, the AWT event thread is also waiting for the SWT thread to free up in order to handle events. I believed I clicked on a view, and then quickly switch focus to another view when this happen. So my theory is that the AWT event thread is busy handling events from my previous mouse click, while we request focus on the SWT thread.

I am not sure what to do at this point. I have previously tried not calling IlvSwingControl.setFocus, and instead direct the call to AWT-event thread and use the underlying JComponent to set focus. However, this causes issues in Eclipse, and the focus is not always correct.

Can you please advise what I can do with this problem? Am I supposed to call IlvSwingControl.setFocus at all?

Thanks...
Samantha
Updated on 2013-01-08T12:02:28Z at 2013-01-08T12:02:28Z by slowhand
  • slowhand
    slowhand
    113 Posts

    Re: IlvSwingControl.setFocus causes Eclipse to hang

    ‏2012-09-26T20:57:26Z  
    In this situation I would try to add the JVM option
    -Dilog.views.swt.noDeadlocks=true
    or invoke
    System.setProperty("ilog.views.swt.noDeadlocks", "true");

    This will guarantee that the JViews ilog.views.swt code does not call invokeAndWait()
    any more.

    But this can cause the resizing / layout of controls to look incorrect. To avoid that,
    it is recommended that for every invocation of "new IlvSwingControl(...)" you override the
    method getLayoutAncestor, like this:

     new IlvSwingControl(shell, SWT.BORDER, chart) {
    @Override
    protected Composite getLayoutAncestor() {
    return shell;
    }
    };
    This applies to JViews 8.8 patch 1 or newer, JViews 8.7 patch 13 or newer, or
    JViews 8.6 patch 25 or newer.

    The documentation for method getLayoutAncestor is as follows:

    Returns the topmost ancestor control that needs to be notified and
    relayouted if the preferred, minimum, or maximum sizes of the embedded
    AWT component have changed. Returns null if no such relayout
    should happen (but then, this control may appear clipped).

    You should usually implement this method. Often getParent() or getParent().getParent() is the right choice. Sometimes
    you have to follow the ancestor chain until you reach the first instance
    of ScrolledComposite.
    @see #preferredSizeChanged(Point, Point, Point)

  • SystemAdmin
    SystemAdmin
    2606 Posts

    Re: IlvSwingControl.setFocus causes Eclipse to hang

    ‏2013-01-07T19:59:50Z  
    • slowhand
    • ‏2012-09-26T20:57:26Z
    In this situation I would try to add the JVM option
    -Dilog.views.swt.noDeadlocks=true
    or invoke
    System.setProperty("ilog.views.swt.noDeadlocks", "true");

    This will guarantee that the JViews ilog.views.swt code does not call invokeAndWait()
    any more.

    But this can cause the resizing / layout of controls to look incorrect. To avoid that,
    it is recommended that for every invocation of "new IlvSwingControl(...)" you override the
    method getLayoutAncestor, like this:

     new IlvSwingControl(shell, SWT.BORDER, chart) {
    @Override
    protected Composite getLayoutAncestor() {
    return shell;
    }
    };
    This applies to JViews 8.8 patch 1 or newer, JViews 8.7 patch 13 or newer, or
    JViews 8.6 patch 25 or newer.

    The documentation for method getLayoutAncestor is as follows:

    Returns the topmost ancestor control that needs to be notified and
    relayouted if the preferred, minimum, or maximum sizes of the embedded
    AWT component have changed. Returns null if no such relayout
    should happen (but then, this control may appear clipped).

    You should usually implement this method. Often getParent() or getParent().getParent() is the right choice. Sometimes
    you have to follow the ancestor chain until you reach the first instance
    of ScrolledComposite.
    @see #preferredSizeChanged(Point, Point, Point)

    A few follow up questions:
    1) Why isn't -Dilog.views.swt.noDeadlocks=true the default if it prevents deadlocks?
    2) Are they any side effects for using this property?
    3) What are the conditions that generate the deadlock in the first place? Is there a specific usage of the ilog components that can cause this?
  • slowhand
    slowhand
    113 Posts

    Re: IlvSwingControl.setFocus causes Eclipse to hang

    ‏2013-01-08T12:02:28Z  
    A few follow up questions:
    1) Why isn't -Dilog.views.swt.noDeadlocks=true the default if it prevents deadlocks?
    2) Are they any side effects for using this property?
    3) What are the conditions that generate the deadlock in the first place? Is there a specific usage of the ilog components that can cause this?
    1) Why isn't -Dilog.views.swt.noDeadlocks=true the default if it prevents deadlocks?

    Because it is not a backward-compatible change: It requires additional code (the getLayoutAncestor method) in order to work satisfactorily.

    2) Are they any side effects for using this property?

    Yes, there can be side effects on layout, as stated above.

    3) What are the conditions that generate the deadlock in the first place? Is there a specific usage of the ilog components that can cause this?

    The deadlocks can appear any time, but focus changes are especially likely to trigger them.

    --slowhand