Java TrayIcon.setToolTip() 在 128 个字符的字符串上使 JVM 崩溃
Java TrayIcon.setToolTip() crashes JVM on String with 128 characters
运行我的 mp3 播放器在播放某些歌曲时崩溃了。
调查一下,事实证明它不是播放器本身,而是 java TrayIcon class,当我用 str.length() == 128.[=13= 调用 setToolTip(str) 时]
我写了一个简短的例子来证明会发生什么:
package jc.javaexceptions;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class Tray_setToolTip {
// testing switches
// if set to true, shows chrash screen
// if set to false, app crashes quietly
static private final boolean SHOW_GUI_FAIL = true;
// does not play a role if run in- or outside EDT
static private final boolean RUN_IN_SWING_DISPATCH_THREAD = true;
/**
* Demonstrates, how setting a 128-char ToolTipText to a TrayIcon will crash the JVM
*/
public static void main(final String[] args) throws AWTException, InvocationTargetException, InterruptedException {
if (SHOW_GUI_FAIL) {
final JFrame f = new JFrame("Test Window, fails at 128 chars ToolTipText length");
f.setBounds(200, 200, 400, 400);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
// create tray image
final int SIZE = 16;
final BufferedImage bi = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_ARGB);
final Graphics g = bi.getGraphics();
g.setColor(Color.CYAN);
g.fillRect(0, 0, SIZE, SIZE);
g.setColor(Color.RED);
g.drawLine(0, 0, SIZE, SIZE);
g.drawLine(0, SIZE, SIZE, 0);
// set up tray and tray icon
final TrayIcon trayIcon = new TrayIcon(bi);
final SystemTray tray = SystemTray.getSystemTray();
trayIcon.addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(final MouseEvent pE) {
tray.remove(trayIcon);
System.exit(0);
}
});
tray.add(trayIcon);
// works fine
System.out.println("1 OK");
trayIcon.setToolTip("Funny Test!"); // -> OK
setTTT(trayIcon, 127); // try 127 -> OK
setTTT(trayIcon, 129); // try 129 -> OK
setTTT(trayIcon, 128); // try 128 -> CRASH // <--------------------------- CRASH
// will not be reached!
System.out.println("End reached!");
}
static private void setTTT(final TrayIcon pTrayIcon, final int pStringLength) throws InvocationTargetException, InterruptedException {
System.out.println("Tray_setToolTip.setTTT(" + pStringLength + ")");
// construct bad-ass string
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < pStringLength; i++) {
sb.append("1");
}
final String str = sb.toString();
System.out.println("\tString len=" + str.length());
if (RUN_IN_SWING_DISPATCH_THREAD) {
// SwingUtilities.invokeLater(() -> pTrayIcon.setToolTip(str)); // cannot use invokeLater(), would allow the output of "End reached!"
SwingUtilities.invokeAndWait(() -> pTrayIcon.setToolTip(str));
} else {
pTrayIcon.setToolTip(str);
}
System.out.println("\tOK");
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
太棒了...您的 PC 上是否也出现这种情况?
还是只在我身上?
我 运行 Oracle jdk-8u40-windows-x64 在最新的 Windows 7...
如果发现这是一个 Java 内部错误,我应该如何进一步处理?
啊是的。已经修复了。如果我的 Eclipse 卡在旧版本 Java 上,当前 (1.8.0_151-b12) 运行它没有任何问题。
傻喵
运行我的 mp3 播放器在播放某些歌曲时崩溃了。 调查一下,事实证明它不是播放器本身,而是 java TrayIcon class,当我用 str.length() == 128.[=13= 调用 setToolTip(str) 时]
我写了一个简短的例子来证明会发生什么:
package jc.javaexceptions;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class Tray_setToolTip {
// testing switches
// if set to true, shows chrash screen
// if set to false, app crashes quietly
static private final boolean SHOW_GUI_FAIL = true;
// does not play a role if run in- or outside EDT
static private final boolean RUN_IN_SWING_DISPATCH_THREAD = true;
/**
* Demonstrates, how setting a 128-char ToolTipText to a TrayIcon will crash the JVM
*/
public static void main(final String[] args) throws AWTException, InvocationTargetException, InterruptedException {
if (SHOW_GUI_FAIL) {
final JFrame f = new JFrame("Test Window, fails at 128 chars ToolTipText length");
f.setBounds(200, 200, 400, 400);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
// create tray image
final int SIZE = 16;
final BufferedImage bi = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_ARGB);
final Graphics g = bi.getGraphics();
g.setColor(Color.CYAN);
g.fillRect(0, 0, SIZE, SIZE);
g.setColor(Color.RED);
g.drawLine(0, 0, SIZE, SIZE);
g.drawLine(0, SIZE, SIZE, 0);
// set up tray and tray icon
final TrayIcon trayIcon = new TrayIcon(bi);
final SystemTray tray = SystemTray.getSystemTray();
trayIcon.addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(final MouseEvent pE) {
tray.remove(trayIcon);
System.exit(0);
}
});
tray.add(trayIcon);
// works fine
System.out.println("1 OK");
trayIcon.setToolTip("Funny Test!"); // -> OK
setTTT(trayIcon, 127); // try 127 -> OK
setTTT(trayIcon, 129); // try 129 -> OK
setTTT(trayIcon, 128); // try 128 -> CRASH // <--------------------------- CRASH
// will not be reached!
System.out.println("End reached!");
}
static private void setTTT(final TrayIcon pTrayIcon, final int pStringLength) throws InvocationTargetException, InterruptedException {
System.out.println("Tray_setToolTip.setTTT(" + pStringLength + ")");
// construct bad-ass string
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < pStringLength; i++) {
sb.append("1");
}
final String str = sb.toString();
System.out.println("\tString len=" + str.length());
if (RUN_IN_SWING_DISPATCH_THREAD) {
// SwingUtilities.invokeLater(() -> pTrayIcon.setToolTip(str)); // cannot use invokeLater(), would allow the output of "End reached!"
SwingUtilities.invokeAndWait(() -> pTrayIcon.setToolTip(str));
} else {
pTrayIcon.setToolTip(str);
}
System.out.println("\tOK");
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
太棒了...您的 PC 上是否也出现这种情况? 还是只在我身上? 我 运行 Oracle jdk-8u40-windows-x64 在最新的 Windows 7...
如果发现这是一个 Java 内部错误,我应该如何进一步处理?
啊是的。已经修复了。如果我的 Eclipse 卡在旧版本 Java 上,当前 (1.8.0_151-b12) 运行它没有任何问题。
傻喵