HotSpot crashes swapping panels

(bug in JRE 5.x, fixed in JRE 6.0)


This test applet was created to reproduce in a simple context Sun JIT crashes that occur in a huge applet using JRE 5.x. 

In both the test applet and the huge applet, the crashes occur when panels with many components are swapped.  Error logs are produced noting that "An unexpected error has been detected by HotSpot Virtual Machine" and the last Java method listed is Component.removeNotify. 

In the huge applet, the crashes occur during normal use, with single clicks of a button to change panels.  However, since these occur only 1% of the time in a huge applet, it is difficult to analyze the problem.  In the test applet the crashes can be evoked by:

The crash logs look very similar in the huge applet (here) and the test applet (here), suggesting that this test applet is exposing the same bug as is seen in the huge applet.  

To reproduce the problem, use the Sun JVM 5.x and click the "Change Panel once" or "Change panel many times" button in the test applet as described above.

The crashes in the huge applet and test applet have been noted only with Sun JVM 5.x but may occur in other versions as well.  The crashes have been noted using three different browsers (Windows versions of Internet Explorer, Firefox and Opera).

A similar crash log is discussed in a thread on Sun's Java forums.

Addendum 1: Downloading the 1 Dec 05 version (build 62) of Sun's Java 6.0 demonstrates that the bug is fixed in that version, both in this test applet and in our huge applet.

Addendum 2: Sun engineers have determined that this applet fails because of two bugs:

It is not clear whether these bugs will get fixed in JRE 1.5, but they are fixed in 1.6.

If you have any insights, workarounds or comments about this test page please contact Mickey Segal.  A listing of  many Java resources is at this link.

Source code:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class StressNotify extends Applet implements ActionListener {

Button onceButton, manyButton;
LabelPanel labelPanelGreen, labelPanelRed;
int panelShowing = -1;
static final int RED = 0;
static final int GREEN = 1;
Panel panel;

public void init()
{
    onceButton = new Button("Change panel once");
    add(onceButton);
    onceButton.addActionListener(this);
    manyButton = new Button("Change panel many times");
    add(manyButton);
    manyButton.addActionListener(this);
    panel = new Panel();
    add(panel);
    addLabelPanel(GREEN);
}

void addLabelPanel(int panelToAdd)
{
    panel.removeAll();
    if (panelToAdd == GREEN)
    {
        labelPanelGreen = new LabelPanel(Color.green);
        panel.add(labelPanelGreen);
    }
    else if (panelToAdd == RED)
    {
        labelPanelRed = new LabelPanel(Color.red);
        panel.add(labelPanelRed);
    }
    panelShowing = panelToAdd;
}

public void actionPerformed(ActionEvent ae)
{
    if (ae.getSource() == onceButton)
    {
        addLabelPanel(1 - panelShowing);
        validate();
    }
    else if (ae.getSource() == manyButton)
    {
        for (int i=0; i<101; i++)
        {
            addLabelPanel(1 - panelShowing);
            validate();
        }
    }
}
} // END OF Class StressNotify


class LabelPanel extends Panel {

int labels = 200;

LabelPanel(Color color)
{
    setLayout(new GridLayout(labels/20, 20, 4, 4));
    setBackground(color);
    Label[] myLabel = new Label[labels];
    for (int i=0; i<labels; i++)
    {
        myLabel[i] = new Label(String.valueOf(i));
        myLabel[i].setBackground(color);
        add(myLabel[i]);
    }
}
} // END OF Class LabelPanel