Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JRE bug?JTable包含某些字符串->;数组下标越界异常_Java_Swing_Unicode_Crash_Fatal Error - Fatal编程技术网

Java JRE bug?JTable包含某些字符串->;数组下标越界异常

Java JRE bug?JTable包含某些字符串->;数组下标越界异常,java,swing,unicode,crash,fatal-error,Java,Swing,Unicode,Crash,Fatal Error,一位用户报告说,某个特定原因导致我们的程序失败。经过调查,似乎将包含该视频标题的字符串添加到JTable会在渲染代码中的某个位置导致ArrayIndexOutOfBoundsException 我们已经在WindowsXP、7和8以及Ubuntu上的Java7U45和Java8(b121)上测试并确认了这一点 下面是一个测试程序,演示了该问题: import javax.swing.*; import java.awt.*; public class TestJTableAIOOBE {

一位用户报告说,某个特定原因导致我们的程序失败。经过调查,似乎将包含该视频标题的字符串添加到JTable会在渲染代码中的某个位置导致ArrayIndexOutOfBoundsException

我们已经在WindowsXP、7和8以及Ubuntu上的Java7U45和Java8(b121)上测试并确认了这一点

下面是一个测试程序,演示了该问题:

import javax.swing.*;
import java.awt.*;

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";

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Font font = findFont();
                if (font == null) {
                    System.out.println("No suitable font found");
                    return;
                }
                System.out.println("Using font: " + font);
                JTable table = new JTable(new Object[][]{{TEXT}}, new Object[]{"title"});
                table.setFont(font);
                JFrame frame = new JFrame();
                frame.add(table);
                frame.pack();
                frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    private static Font findFont() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        for (Font font : ge.getAllFonts()) {
            if (font.canDisplayUpTo(TEXT) == -1) {
                return font.deriveFont(0, 12);
            }
        }
        return null;
    }
}
每次Swing尝试渲染文本时,都会将此堆栈跟踪打印到stderr:

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)
你能复制这个吗?字符串中的什么特性导致了这种情况?这真的是一个JRE bug吗?我应该向甲骨文报告吗

我们已经在Java7U45和Java8(b121)上测试并确认了这一点 在WindowsXP、7和8以及Ubuntu上

JRE bug

  • 不仅仅是删除、替换(字符串中提示2次)

编辑这是JTable的字体问题(已使用)

生成异常

run:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Bugs.Test.<init>(Test.java:28)
    at Bugs.Test$1.run(Test.java:42)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD SUCCESSFUL (total time: 1 second)

该漏洞于2014年1月报告给Oracle,三个月后,它以的身份出现在公共漏洞跟踪器中。2016年9月,Java 9修复了该漏洞。

我们在使用Code2000.ttf呈现Malayalam菜单项时遇到了类似问题

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 280 at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:814) at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:548) at sun.font.ExtendedTextSourceLabel.getCharX(ExtendedTextSourceLabel.java:357) 线程“AWT-EventQueue-0”java.lang.ArrayIndexOutofBounds异常:280 位于sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:814) 位于sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:548) 位于sun.font.ExtendedTextSourceLabel.getCharX(ExtendedTextSourceLabel.java:357) 最终我们发现菜单项名称后面有空格。删除这些文件为我们解决了这个问题


..ede

这可能是一个JDK错误。它似乎正在构建一个边界框,因此可能字体返回的一个标志符号不起作用(可能是一个错误的字体,但Swing应该会进行补偿)。为了缩小范围,我建议逐步从测试字符串中删除单个字符代码的所有实例(例如,删除所有
\u0D02
,然后删除所有
\u0D15
,等等……共有23个)。此外,我还建议在
JTable
中添加一个简单的ASCII列标签。应该没关系,但最好排除零长度字符串的可能性。他们已经知道了。看到了,据说已经修复了,但显然没有。错误报告可能会给您提供更多信息。@kdgregory JDK-6374477看起来确实非常相似,并且没有修复。这份报告来自2006年(对
Font
。:)mKorbel,@AndrewThompson的进一步测试表明,如果仅在计算机上安装了“Arial Unicode MS”字体,则没有例外(无论使用setFont(…)实际设置了哪种字体)。此字体随Microsoft Office提供,默认情况下不包括在Windows中。@ntoskrnl-Huh。这很有趣,是的,我确实安装了
Font
(以及MS Office)。
import java.awt.*;
import java.awt.event.*;
import java.util.Locale;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.table.DefaultTableModel;

public class SystemFontDisplayer extends JFrame {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame("Nimbus UIDeafaults and Font");
    private JComboBox fontsBox;
    private javax.swing.Timer timer = null;
    private String buggyConstalation = "Jesus appear in Knife \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 JButton testButton = new JButton(buggyConstalation);
    private JTextField testTextField = new JTextField(buggyConstalation);
    private JLabel testLabel = new JLabel(buggyConstalation);//caused by \u200D
    private JTable table;
    private DefaultTableModel model;

    public SystemFontDisplayer() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontFamilyNames = ge.getAvailableFontFamilyNames(Locale.getDefault());
        fontsBox = new JComboBox(fontFamilyNames);
        fontsBox.setSelectedItem("SansSerif");
        fontsBox.setRenderer(new ComboRenderer());
        fontsBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    final String fontName = fontsBox.getSelectedItem().toString();
                    fontsBox.setFont(new Font(fontName, Font.PLAIN, 16));
                    start();
                }
            }
        });
        fontsBox.setSelectedItem(0);
        fontsBox.getEditor().selectAll();
        model = new DefaultTableModel(
                new Object[][]{{buggyConstalation,buggyConstalation},}, 
                new String[]{"Col 1","Col 2",});
        table = new JTable(model);        
        frame.setLayout(new GridLayout(5, 0, 20, 20));
        frame.add(fontsBox);
        frame.add(testButton);
        frame.add(testTextField);
        frame.add(testLabel);
        frame.add(table);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(200, 105);
        frame.pack();
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                fontsBox.setPopupVisible(true);
                fontsBox.setPopupVisible(false);
            }
        });
        frame.setVisible(true);
    }

    private void start() {
        timer = new javax.swing.Timer(750, updateCol());
        timer.setRepeats(false);
        timer.start();
    }

    public Action updateCol() {
        return new AbstractAction("text load action") {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                final Font fnt = new Font(fontsBox.getSelectedItem().toString(), Font.PLAIN, 12);
                final FontUIResource res = new FontUIResource(fnt);
                UIManager.getLookAndFeelDefaults().put("Button.font", res);
                UIManager.getLookAndFeelDefaults().put("TextField.font", res);
                UIManager.getLookAndFeelDefaults().put("Label.font", res);
                UIManager.getLookAndFeelDefaults().put("Table.font", res);
                SwingUtilities.updateComponentTreeUI(frame);
            }
        };
    }

    public static void main(String arg[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                SystemFontDisplayer systemFontDisplayer = new SystemFontDisplayer();
            }
        });
    }

    private class ComboRenderer extends BasicComboBoxRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            final Object fntObj = value;
            final String fontFamilyName = (String) fntObj;
            setFont(new Font(fontFamilyName, Font.PLAIN, 16));
            return this;
        }
    }
}
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 280 at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:814) at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:548) at sun.font.ExtendedTextSourceLabel.getCharX(ExtendedTextSourceLabel.java:357)