-
Bug
-
Resolution: Fixed
-
P3
-
6u45, 7u45, 8, 9
-
b137
-
windows_7
FULL PRODUCT VERSION :
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b63, mixed mode)
A DESCRIPTION OF THE PROBLEM :
A user reported that a certain online video causes our application to fail. Upon investigation it seems that adding a string containing the title of the video to a JTable causes an ArrayIndexOutOfBoundsException somewhere in the rendering code.
Specifically, this issue occurs if a word containing a certain kind of string is truncated to fit in the table (with "..."). (To observe this, try adding a long ASCII-only word at the beginning of the string and then resizing the frame manually.)
However, there is a catch. Everything works correctly if the "Arial Unicode MS" font is merely *installed* on the computer (*no matter which font is actually set* using setFont(...)). This font comes with Microsoft Office and is not included in Windows by default.
We tested this extensively on both Java 7u45 and Java 8 (b121) on Windows 7 and 8. This was also reproduced on Windows XP and Ubuntu.
ADDITIONAL REGRESSION INFORMATION:
The test case additionally causes a JVM crash in 7u25, but that is already fixed in 7u45 and 8 (b121).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Run the test case on a newly installed Windows 7 system without any extra programs installed. Observe behavior. (Exception occurs.)
- Install the Arial Unicode font, either by installing Microsoft Office or by copying the file from another system.
- Run the test case again and observe behavior. (No exceptions occur.)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Frame correctly rendered and no exceptions, no matter which fonts are installed or set.
ACTUAL -
stdout: Arial Unicode is not installed
stdout: Testing with font: java.awt.Font[family=Kartika,name=Kartika,style=plain,size=12]
[...frame not properly rendered, exceptions printed...]
[...close the window...]
stdout: Testing with font: javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
[...frame not properly rendered, exceptions printed...]
[...close the window...]
stdout: Testing with font: java.awt.Font[family=Arial Unicode MS,name=Arial Unicode MS,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
stdout: Testing with font: java.awt.Font[family=Kartika,name=Kartika,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
stdout: Testing with font: javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 48
at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:814)
at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:548)
at sun.font.ExtendedTextSourceLabel.getLineBreakIndex(ExtendedTextSourceLabel.java:480)
at java.awt.font.TextMeasurer.calcLineBreak(TextMeasurer.java:330)
at java.awt.font.TextMeasurer.getLineBreakIndex(TextMeasurer.java:566)
at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:359)
at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:328)
at sun.swing.SwingUtilities2.clipString(SwingUtilities2.java:472)
at javax.swing.SwingUtilities.layoutCompoundLabelImpl(SwingUtilities.java:1023)
at javax.swing.SwingUtilities.layoutCompoundLabel(SwingUtilities.java:892)
at javax.swing.plaf.basic.BasicLabelUI.layoutCL(BasicLabelUI.java:94)
at javax.swing.plaf.basic.BasicLabelUI.layout(BasicLabelUI.java:201)
at javax.swing.plaf.basic.BasicLabelUI.paint(BasicLabelUI.java:164)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:777)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:151)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2115)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:777)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paint(JComponent.java:1062)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paint(JComponent.java:1062)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5224)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1532)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1455)
at javax.swing.RepaintManager.paint(RepaintManager.java:1252)
at javax.swing.JComponent.paint(JComponent.java:1039)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1973)
at java.awt.Window.paint(Window.java:3901)
at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CountDownLatch;
public class TestJTableAIOOBE {
private static final String TEXT = "\u0D38\u0D4D\u0D31\u0D4D\u0D31\u0D40\u0D32\u0D4D\u200D \u0D15\u0D31\u0D3F\u0D15\u0D4D\u0D15\u0D24\u0D4D\u0D24\u0D3F\u0D2F\u0D3F\u0D32\u0D4D\u200D \u0D2F\u0D47\u0D36\u0D41\u0D15\u0D4D\u0D30\u0D3F\u0D38\u0D4D\u0D24\u0D41\u0D35\u0D3F\u0D28\u0D4D\u0D31\u0D46 \u0D30\u0D42\u0D2A\u0D02 \u0D2A\u0D4D\u0D30\u0D24\u0D4D\u0D2F\u0D15\u0D4D\u0D37\u0D2A\u0D4D\u0D2A\u0D46\u0D1F\u0D4D\u0D1F\u0D41";
private static CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
Font font = findArialUnicode();
if (font != null) {
createFrame(font);
latch.await();
latch = new CountDownLatch(1);
} else {
System.out.println("Arial Unicode is not installed");
}
font = findOtherSuitableFont();
if (font != null) {
createFrame(font);
latch.await();
} else {
System.out.println("No other suitable font found");
}
createFrame(null);
}
private static void createFrame(final Font font) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(new Object[][]{{TEXT}}, new Object[]{"title"});
if (font != null) {
table.setFont(font);
}
System.out.println("Testing with font: " + table.getFont());
JFrame frame = new JFrame();
frame.add(table);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latch.countDown();
}
});
frame.setVisible(true);
}
});
}
private static Font findArialUnicode() {
for (Font font : getAllFonts()) {
if (font.getName().equals("Arial Unicode MS")) {
return font.deriveFont(0, 12);
}
}
return null;
}
private static Font findOtherSuitableFont() {
for (Font font : getAllFonts()) {
if (!font.getName().equals("Arial Unicode MS")
&& font.canDisplayUpTo(TEXT) == -1) {
return font.deriveFont(0, 12);
}
}
return null;
}
private static Font[] getAllFonts() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
}
}
---------- END SOURCE ----------
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b63, mixed mode)
A DESCRIPTION OF THE PROBLEM :
A user reported that a certain online video causes our application to fail. Upon investigation it seems that adding a string containing the title of the video to a JTable causes an ArrayIndexOutOfBoundsException somewhere in the rendering code.
Specifically, this issue occurs if a word containing a certain kind of string is truncated to fit in the table (with "..."). (To observe this, try adding a long ASCII-only word at the beginning of the string and then resizing the frame manually.)
However, there is a catch. Everything works correctly if the "Arial Unicode MS" font is merely *installed* on the computer (*no matter which font is actually set* using setFont(...)). This font comes with Microsoft Office and is not included in Windows by default.
We tested this extensively on both Java 7u45 and Java 8 (b121) on Windows 7 and 8. This was also reproduced on Windows XP and Ubuntu.
ADDITIONAL REGRESSION INFORMATION:
The test case additionally causes a JVM crash in 7u25, but that is already fixed in 7u45 and 8 (b121).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Run the test case on a newly installed Windows 7 system without any extra programs installed. Observe behavior. (Exception occurs.)
- Install the Arial Unicode font, either by installing Microsoft Office or by copying the file from another system.
- Run the test case again and observe behavior. (No exceptions occur.)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Frame correctly rendered and no exceptions, no matter which fonts are installed or set.
ACTUAL -
stdout: Arial Unicode is not installed
stdout: Testing with font: java.awt.Font[family=Kartika,name=Kartika,style=plain,size=12]
[...frame not properly rendered, exceptions printed...]
[...close the window...]
stdout: Testing with font: javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
[...frame not properly rendered, exceptions printed...]
[...close the window...]
stdout: Testing with font: java.awt.Font[family=Arial Unicode MS,name=Arial Unicode MS,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
stdout: Testing with font: java.awt.Font[family=Kartika,name=Kartika,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
stdout: Testing with font: javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
[...frame correctly rendered, no exceptions...]
[...close the window...]
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 48
at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:814)
at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:548)
at sun.font.ExtendedTextSourceLabel.getLineBreakIndex(ExtendedTextSourceLabel.java:480)
at java.awt.font.TextMeasurer.calcLineBreak(TextMeasurer.java:330)
at java.awt.font.TextMeasurer.getLineBreakIndex(TextMeasurer.java:566)
at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:359)
at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:328)
at sun.swing.SwingUtilities2.clipString(SwingUtilities2.java:472)
at javax.swing.SwingUtilities.layoutCompoundLabelImpl(SwingUtilities.java:1023)
at javax.swing.SwingUtilities.layoutCompoundLabel(SwingUtilities.java:892)
at javax.swing.plaf.basic.BasicLabelUI.layoutCL(BasicLabelUI.java:94)
at javax.swing.plaf.basic.BasicLabelUI.layout(BasicLabelUI.java:201)
at javax.swing.plaf.basic.BasicLabelUI.paint(BasicLabelUI.java:164)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:777)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:151)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2115)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:777)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paint(JComponent.java:1062)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paint(JComponent.java:1062)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:886)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5224)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1532)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1455)
at javax.swing.RepaintManager.paint(RepaintManager.java:1252)
at javax.swing.JComponent.paint(JComponent.java:1039)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1973)
at java.awt.Window.paint(Window.java:3901)
at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CountDownLatch;
public class TestJTableAIOOBE {
private static final String TEXT = "\u0D38\u0D4D\u0D31\u0D4D\u0D31\u0D40\u0D32\u0D4D\u200D \u0D15\u0D31\u0D3F\u0D15\u0D4D\u0D15\u0D24\u0D4D\u0D24\u0D3F\u0D2F\u0D3F\u0D32\u0D4D\u200D \u0D2F\u0D47\u0D36\u0D41\u0D15\u0D4D\u0D30\u0D3F\u0D38\u0D4D\u0D24\u0D41\u0D35\u0D3F\u0D28\u0D4D\u0D31\u0D46 \u0D30\u0D42\u0D2A\u0D02 \u0D2A\u0D4D\u0D30\u0D24\u0D4D\u0D2F\u0D15\u0D4D\u0D37\u0D2A\u0D4D\u0D2A\u0D46\u0D1F\u0D4D\u0D1F\u0D41";
private static CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
Font font = findArialUnicode();
if (font != null) {
createFrame(font);
latch.await();
latch = new CountDownLatch(1);
} else {
System.out.println("Arial Unicode is not installed");
}
font = findOtherSuitableFont();
if (font != null) {
createFrame(font);
latch.await();
} else {
System.out.println("No other suitable font found");
}
createFrame(null);
}
private static void createFrame(final Font font) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(new Object[][]{{TEXT}}, new Object[]{"title"});
if (font != null) {
table.setFont(font);
}
System.out.println("Testing with font: " + table.getFont());
JFrame frame = new JFrame();
frame.add(table);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latch.countDown();
}
});
frame.setVisible(true);
}
});
}
private static Font findArialUnicode() {
for (Font font : getAllFonts()) {
if (font.getName().equals("Arial Unicode MS")) {
return font.deriveFont(0, 12);
}
}
return null;
}
private static Font findOtherSuitableFont() {
for (Font font : getAllFonts()) {
if (!font.getName().equals("Arial Unicode MS")
&& font.canDisplayUpTo(TEXT) == -1) {
return font.deriveFont(0, 12);
}
}
return null;
}
private static Font[] getAllFonts() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
}
}
---------- END SOURCE ----------