JDK-6361892 : Printing of HTML through JEditorPane is broken since Mustang-b53
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-12-12
  • Updated: 2011-01-27
  • Resolved: 2006-01-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b66Fixed
Related Reports
Relates :  
Relates :  
Description
I am opening a sample HTML file in JEditorPane and printing it by calling JEditorPane.print(). The dialog opens up and I am clicking the print button. After that, the interactive dialog is shown with the message 'Printing in progress' and the application hangs. Application stops responding to any of the user inputs and the interactive dialog just stays there for ever. 

This is reproducible on Mustang-b53 but not reproducible on Mustang-b51. This is noticed on WinXP as well as Solaris-Sparc10. Looks like this is a regression introduced in Mustang-b52 or 53. Printing a text file works properly.

I have attached a sample test. Execute it as follows. 
'java JEditorPaneTest sample_html.html'
Click the print button. A print dialog will open up. Click on the print button. If the application hangs after that and if the interactive dialog stays on the screen forever, the bug is reproduced.

Here is the thread dump at the time of hang:

Full thread dump Java HotSpot(TM) Client VM (1.6.0-rc-b63 mixed mode):

"Thread-4" prio=6 tid=0x0ade7d00 nid=0x1098 waiting on condition [0x0e64f000..0x
0e64fd14]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x029b6aa0> (a java.util.concurrent.FutureTask$S
ync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:145)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:705)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared
Interruptibly(AbstractQueuedSynchronizer.java:861)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedIn
terruptibly(AbstractQueuedSynchronizer.java:1170)
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:219)
        at java.util.concurrent.FutureTask.get(FutureTask.java:84)
        at sun.swing.text.TextComponentPrintable.print(TextComponentPrintable.ja
va:382)
        at sun.swing.PrintingStatus$NotificationPrintable.print(PrintingStatus.j
ava:248)
        at sun.print.RasterPrinterJob.printPage(RasterPrinterJob.java:1902)
        at sun.print.RasterPrinterJob.print(RasterPrinterJob.java:1397)
        at javax.swing.text.JTextComponent$1.call(JTextComponent.java:2295)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:288)
        at java.util.concurrent.FutureTask.run(FutureTask.java:139)
        at javax.swing.text.AbstractDocument.render(AbstractDocument.java:403)
        at javax.swing.text.JTextComponent$2.run(JTextComponent.java:2312)
        at java.lang.Thread.run(Thread.java:626)

"Thread-3" daemon prio=6 tid=0x0ae55000 nid=0x4458 runnable [0x0b1af000..0x0b1af
a94]
   java.lang.Thread.State: RUNNABLE
        at sun.print.Win32PrintServiceLookup.notifyPrinterChange(Native Method)
        at sun.print.Win32PrintServiceLookup.access$100(Win32PrintServiceLookup.
java:32)
        at sun.print.Win32PrintServiceLookup$PrinterChangeListener.run(Win32Prin
tServiceLookup.java:302)

"TimerQueue" daemon prio=6 tid=0x0adc6d00 nid=0x6634 in Object.wait() [0x0c02f00
0..0x0c02fb14]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02fef398> (a javax.swing.TimerQueue)
        at javax.swing.TimerQueue.run(TimerQueue.java:233)
        - locked <0x02fef398> (a javax.swing.TimerQueue)
        at java.lang.Thread.run(Thread.java:626)

"DestroyJavaVM" prio=6 tid=0x00036e00 nid=0x6078 waiting on condition [0x0000000
0..0x008ffd4c]
   java.lang.Thread.State: RUNNABLE

"AWT-EventQueue-0" prio=6 tid=0x0ae64900 nid=0x4d00 in Object.wait() [0x0be0e000
..0x0be0fc94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02f15ad8> (a javax.swing.text.html.HTMLDocument)
        at java.lang.Object.wait(Object.java:484)
        at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:132
9)
        - locked <0x02f15ad8> (a javax.swing.text.html.HTMLDocument)
        at javax.swing.text.DefaultStyledDocument$ChangeUpdateRunnable.run(Defau
ltStyledDocument.java:2475)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
ad.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:183)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:177)
        at java.awt.Dialog$1.run(Dialog.java:1032)
        at java.awt.Dialog$2.run(Dialog.java:1078)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1076)
        at java.awt.Component.show(Component.java:1406)
        at java.awt.Component.setVisible(Component.java:1359)
        at java.awt.Window.setVisible(Window.java:695)
        at java.awt.Dialog.setVisible(Dialog.java:972)
        at sun.swing.PrintingStatus.showModalOnEDT(PrintingStatus.java:181)
        at sun.swing.PrintingStatus.showModal(PrintingStatus.java:150)
        at javax.swing.text.JTextComponent.print(JTextComponent.java:2321)
        at JEditorPaneTest.actionPerformed(JEditorPaneTest.java:62)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:19
57)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.jav
a:2280)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel
.java:377)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:232
)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonL
istener.java:234)
        at java.awt.Component.processMouseEvent(Component.java:5957)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3282)
        at java.awt.Component.processEvent(Component.java:5722)
        at java.awt.Container.processEvent(Container.java:1960)
        at java.awt.Component.dispatchEventImpl(Component.java:4365)
        at java.awt.Container.dispatchEventImpl(Container.java:2018)
        at java.awt.Component.dispatchEvent(Component.java:4195)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4222
)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3886)

        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3816)
        at java.awt.Container.dispatchEventImpl(Container.java:2004)
        at java.awt.Window.dispatchEventImpl(Window.java:2300)
        at java.awt.Component.dispatchEvent(Component.java:4195)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
ad.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)

        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)

        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

"AWT-Shutdown" prio=6 tid=0x0ae64400 nid=0x6684 in Object.wait() [0x0bdbf000..0x
0bdbfd14]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02e6e258> (a java.lang.Object)
        at java.lang.Object.wait(Object.java:484)
        at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:259)
        - locked <0x02e6e258> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:626)

"AWT-Windows" daemon prio=6 tid=0x0ade8100 nid=0x29a4 runnable [0x0b07f000..0x0b
07fa94]
   java.lang.Thread.State: RUNNABLE
        at sun.awt.windows.WToolkit.eventLoop(Native Method)
        at sun.awt.windows.WToolkit.run(WToolkit.java:290)
        at java.lang.Thread.run(Thread.java:626)

"Java2D Disposer" daemon prio=10 tid=0x0ada1600 nid=0x4f68 in Object.wait() [0x0
afdf000..0x0afdfb94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02ebab08> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0x02ebab08> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at sun.java2d.Disposer.run(Disposer.java:125)
        at java.lang.Thread.run(Thread.java:626)

"Low Memory Detector" daemon prio=6 tid=0x0aaf5800 nid=0x5aa0 runnable [0x000000
00..0x00000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x0aaf3300 nid=0x64ec waiting on condition
[0x00000000..0x0acdf764]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" daemon prio=10 tid=0x0aaf2300 nid=0x5ab0 runnable [0x00000000.
.0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x0aaf1900 nid=0x4cac waiting on conditio
n [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=8 tid=0x0aae5600 nid=0x1710 in Object.wait() [0x0abef000
..0x0abefa94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02ebad60> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0x02ebad60> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x0aae1500 nid=0x62ec in Object.wait() [0
x0ab9f000..0x0ab9fb14]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02ebadf0> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:484)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0x02ebadf0> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x0aade600 nid=0x55c8 runnable

"VM Periodic Task Thread" prio=10 tid=0x0aaf6b00 nid=0x5438 waiting on condition


JNI global references: 1314

Heap
 def new generation   total 960K, used 298K [0x02980000, 0x02a80000, 0x02e60000)

  eden space 896K,  26% used [0x02980000, 0x029baac0, 0x02a60000)
  from space 64K, 100% used [0x02a60000, 0x02a70000, 0x02a70000)
  to   space 64K,   0% used [0x02a70000, 0x02a70000, 0x02a80000)
 tenured generation   total 4096K, used 1743K [0x02e60000, 0x03260000, 0x0698000
0)
   the space 4096K,  42% used [0x02e60000, 0x03013f88, 0x03014000, 0x03260000)
 compacting perm gen  total 12288K, used 10518K [0x06980000, 0x07580000, 0x0a980
000)
   the space 12288K,  85% used [0x06980000, 0x073c5838, 0x073c5a00, 0x07580000)
No shared spaces configured.

Comments
EVALUATION This is a regression introduced by the fix for 5062649 REG: JEditorPane/JTextPane(J2SE1.5) No support for dynamic Fonts After the fix BasicEditorPaneUI modifies document styles on some events. Changing styles requires write lock for the document. Printing thread holds read lock thus we have a deadlock. Changing style takes the write lock even if new value is the same as the old one. For the printing case document style has all the correct values already. We do not need to change them. Thus we will avoid the deadlock. I suggest not to modify style if the current value is the same as the new one. -- *** /tmp/geta14713 Mon Dec 12 14:54:45 2005 --- BasicEditorPaneUI.java Mon Dec 12 14:48:34 2005 *************** *** 268,274 **** } } Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE); ! style.removeAttribute(FONT_ATTRIBUTE_KEY); } } --- 268,276 ---- } } Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE); ! if (style.getAttribute(FONT_ATTRIBUTE_KEY) != null) { ! style.removeAttribute(FONT_ATTRIBUTE_KEY); ! } } } *************** *** 298,304 **** documentStyleSheet.addRule("BASE_SIZE " + component.getFont().getSize()); Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE); ! style.addAttribute(FONT_ATTRIBUTE_KEY, font); } } --- 300,308 ---- documentStyleSheet.addRule("BASE_SIZE " + component.getFont().getSize()); Style style = ((StyledDocument) document).getStyle(StyleContext.DEFAULT_STYLE); ! if (! font.equals(style.getAttribute(FONT_ATTRIBUTE_KEY))) { ! style.addAttribute(FONT_ATTRIBUTE_KEY, font); ! } } } --
12-12-2005