Deadlock in bei modalen Dialogen in Forms
3 posts
• Page 1 of 1
Deadlock in bei modalen Dialogen in Forms
Hi!
Bei uns ist ein netter Deadlock aufgefallen (natürlich nicht 100% reproduzierbar), der dann auftritt, wenn man in der Oracle Forms Anbindung einen modalen UIInternalFrame erzeugt, welcher auch noch UIEditors enthält. Ich bin mir ziemlich sicher die Ursache ermittelt zu haben, nur ich komme nicht auf einen Workaround um das halbwegs schnell zu beheben.
Diese beiden Threads locken sich:
Was man nicht sieht ist, dass AbstractDocument hier
einen writeLockerzeugt, das wird später noch wichtig.
Im Endeffekt passiert folgendes:
Ich hoffe, das ist halbwegs nachvollziehbar. Mir fällt leider momentan keine Lösung ein. Am einfachsten wäre es, Forms beizubringen die Komponenten nicht sofort zu zeichnen, sondern normal ein Repaint auszulösen (wäre nicht das erste Mal). Leider kann ich hier nicht irgendwie per Reflection rein wie sonst immer.
Wenn ich mir die Problematik so ansehe bin ich generell verwundert, dass das nicht öfters passiert.
Für Vorschläge jedweder Art bin ich offen
Danke!
Bei uns ist ein netter Deadlock aufgefallen (natürlich nicht 100% reproduzierbar), der dann auftritt, wenn man in der Oracle Forms Anbindung einen modalen UIInternalFrame erzeugt, welcher auch noch UIEditors enthält. Ich bin mir ziemlich sicher die Ursache ermittelt zu haben, nur ich komme nicht auf einen Workaround um das halbwegs schnell zu beheben.
Diese beiden Threads locken sich:
- Code: Select all
"Forms-DialogThread7" prio=6 tid=0x06ca1400 nid=0x1f90 in Object.wait() [0x0898d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x2d5c4ce0> (a javax.swing.text.PlainDocument)
at java.lang.Object.wait(Object.java:503)
at javax.swing.text.AbstractDocument.readLock(Unknown Source)
- locked <0x2d5c4ce0> (a javax.swing.text.PlainDocument)
at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTextFieldUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTextFieldUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
- locked <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
- locked <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
- locked <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
- locked <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
- locked <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at javax.swing.JComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.lwWindow.LWWindow.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.EwtComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.EwtComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.LWComponent._paintComponent(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintExtents(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paint(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.JBufferedPanel.paintImmediate(JBufferedPanel.java:213)
at oracle.ewt.lwAWT.JBufferedPanel.paintImmediateUnclipped(JBufferedPanel.java:217)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paintImmediateUnclipped(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paintImmediateUnclipped(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paintImmediateUnclipped(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paintImmediateUnclipped(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.paintImmediateUnclipped(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.paintImmediate(Unknown Source)
at oracle.ewt.lwAWT.SharedPainter.unfreezeRepaints(Unknown Source)
at oracle.ewt.lwAWT.LWComponent.unfreezeRepaints(Unknown Source)
at oracle.ewt.lwAWT.lwWindow.LWWindow.setVisible(Unknown Source)
at oracle.ewt.lwAWT.lwWindow.LWWindow.setVisible(Unknown Source)
at oracle.forms.handler.DialogThread.doDialog(Unknown Source)
at oracle.forms.handler.DialogThread.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
"AWT-EventQueue-0" prio=6 tid=0x0530d000 nid=0x1390 waiting for monitor entry [0x058ce000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.awt.Component.invalidate(Unknown Source)
- waiting to lock <0x28e7f078> (a java.awt.Component$AWTTreeLock)
at java.awt.Container.invalidate(Unknown Source)
at javax.swing.JComponent.revalidate(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI$RootView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.PlainView.updateDamage(Unknown Source)
at javax.swing.text.PlainView.removeUpdate(Unknown Source)
at javax.swing.text.FieldView.removeUpdate(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI$RootView.removeUpdate(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI$UpdateHandler.removeUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.fireRemoveUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.handleRemove(Unknown Source)
at javax.swing.text.AbstractDocument$DefaultFilterBypass.replace(Unknown Source)
at com.sibvisions.rad.ui.swing.ext.celleditor.JVxTextCellEditor$CellEditorHandler.replaceAllowed(JVxTextCellEditor.java:760)
at com.sibvisions.rad.ui.swing.ext.celleditor.JVxTextCellEditor$CellEditorHandler.access$100(JVxTextCellEditor.java:178)
at com.sibvisions.rad.ui.swing.ext.celleditor.JVxTextCellEditor$CellEditorHandler$TextDocumentFilter.replace(JVxTextCellEditor.java:808)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.setText(Unknown Source)
at com.sibvisions.rad.ui.swing.ext.celleditor.JVxTextCellEditor$CellEditorHandler.cancelEditing(JVxTextCellEditor.java:393)
at com.sibvisions.rad.ui.swing.ext.JVxEditor.cancelEditing(JVxEditor.java:439)
at com.sibvisions.rad.ui.swing.ext.JVxEditor.run(JVxEditor.java:400)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Was man nicht sieht ist, dass AbstractDocument hier
- Code: Select all
javax.swing.text.AbstractDocument.replace(Unknown Source)
einen writeLockerzeugt, das wird später noch wichtig.
Im Endeffekt passiert folgendes:
- wir erzeugen ein Panel ähnlich einem Workscreen mit MemDataBook und Editoren
- dieser wird per ProjX.openContent als modaler Dialog aufgerufen
- FoInternalFrameWindow wird als ressource zum internen Frame erzeugt
- dessen setVisible Methode ruft wiederum DialogThread.showDialog auf
- ab jetz sind wir in einem neuen "Forms-DialogThread7"
- addnotify im JVxEditor führt dazu, dass cancelEditing in ein invokeLater eingepackt wird
- inzwischen ist der DialogThread fertig mit initialisieren und fängt an zu zeichnen
- cancelEditing im AWT-Thread löst mittels replace (hier wird der writeLock gesetzt) ein invalidate aus, es wird versucht den AWTTreeLock zu bekommen
- dieser Lock ist jedoch in der zwischenzeit vom DialogThread durchs Zeichnen besetzt
- der DialogThread kann den Editor nicht zeichnen, da noch darauf gewartet wird, bis der writeLock aufgehoben wird
Ich hoffe, das ist halbwegs nachvollziehbar. Mir fällt leider momentan keine Lösung ein. Am einfachsten wäre es, Forms beizubringen die Komponenten nicht sofort zu zeichnen, sondern normal ein Repaint auszulösen (wäre nicht das erste Mal). Leider kann ich hier nicht irgendwie per Reflection rein wie sonst immer.
Wenn ich mir die Problematik so ansehe bin ich generell verwundert, dass das nicht öfters passiert.
Für Vorschläge jedweder Art bin ich offen
Danke!
- manfrede
- Posts: 21
- Joined: Tue Oct 22, 2013 11:45 am
Re: Deadlock in bei modalen Dialogen in Forms
Eindeutig ein Swing Problem. Sie können nicht wirklich etwas dagegen tun.
In JVx müsste vor dem setText des CellEditors ein AWT TreeLock angefordert werden um das Problem zu lösen.
In JVx müsste vor dem setText des CellEditors ein AWT TreeLock angefordert werden um das Problem zu lösen.
-
Development@SIB - Posts: 325
- Joined: Mon Sep 28, 2009 1:54 pm
Re: Deadlock in bei modalen Dialogen in Forms
Da das in letzter Zeit etwas häufiger auftritt habe ich wie von Ihnen beschrieben versucht, das Setzen des Textes in ein synchronized zu packen
JVxTextCellEditor:
ähnliches z.B. auch im JVxNumberCellEditor.
Bisher habe ich keine Nebenwirkungen beobachten können. Beim Debuggen habe ich auch gesehn, dass der Forms-Dialog Thread brav stehen bleibt und wartet bis der Text gesetzt wurde.
Irgendeine Idee dazu ob das Fehler an anderen Stellen produzieren kann? Ansonsten würde ich das gerne produktiv einsetzen.
JVxTextCellEditor:
- Code: Select all
synchronized (textComponent.getTreeLock()){
textComponent.setText(value);
}
ähnliches z.B. auch im JVxNumberCellEditor.
Bisher habe ich keine Nebenwirkungen beobachten können. Beim Debuggen habe ich auch gesehn, dass der Forms-Dialog Thread brav stehen bleibt und wartet bis der Text gesetzt wurde.
Irgendeine Idee dazu ob das Fehler an anderen Stellen produzieren kann? Ansonsten würde ich das gerne produktiv einsetzen.
- manfrede
- Posts: 21
- Joined: Tue Oct 22, 2013 11:45 am
3 posts
• Page 1 of 1