United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7193219 JComboBox serialization fails in JDK 1.7
JDK-7193219 : JComboBox serialization fails in JDK 1.7

Details
Type:
Bug
Submit Date:
2012-08-22
Status:
Closed
Updated Date:
2013-04-20
Project Name:
JDK
Resolved Date:
2012-10-24
Component:
client-libs
OS:
generic
Sub-Component:
java.awt
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
7u40 (b08)

Related Reports
Backport:
Backport:
Backport:
Backport:
Backport:
Backport:
Backport:
Backport:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b06)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows and Oracle Solaris

A DESCRIPTION OF THE PROBLEM :
Deserialization of java.awt.Container, which has JComboBox and which was previously added to JFrame, produces NullPointerException on JDK 1.7, while on JDK 1.6 and 1.5 it does not.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached source code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both windows with titles ???why why why ??? and ???deserialize ??? and with identical contents should be displayed on the desktop. No exception should be thrown.
ACTUAL -
NullPointerException is thrown (see below).

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
         at java.awt.Container.updateGraphicsData(Container.java:1149)
         at java.awt.Container.updateGraphicsData(Container.java:1151)
         at java.awt.Container.updateGraphicsData(Container.java:1151)
         at java.awt.Container.updateGraphicsData(Container.java:1151)
         at java.awt.Container.updateGraphicsData(Container.java:1151)
         at java.awt.Component.setGraphicsConfiguration(Component.java:1152)
         at java.awt.Window.setGraphicsConfiguration(Window.java:3144)
         at java.awt.Window.initGC(Window.java:470)
         at java.awt.Window.initDeserializedWindow(Window.java:2954)
         at java.awt.Window.readObject(Window.java:3042)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.lang.reflect.Method.invoke(Method.java:601)
         at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)

         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
         at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)

         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
         at java.beans.PropertyChangeSupport.readObject(PropertyChangeSupport.java:468)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.lang.reflect.Method.invoke(Method.java:601)
         at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)

         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
         at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
         at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:498)
         at java.awt.Component.readObject(Component.java:8681)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.lang.reflect.Method.invoke(Method.java:601)
         at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
         at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)

         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
         at MainTest.test(MainTest.java:65)
         at MainTest.access$100(MainTest.java:15)
         at MainTest$1.run(MainTest.java:91)
         at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
         at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
         at java.awt.EventQueue.access$000(EventQueue.java:102)
         at java.awt.EventQueue$3.run(EventQueue.java:662)
         at java.awt.EventQueue$3.run(EventQueue.java:660)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
         at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
         at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
         at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
         at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)

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

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

REPRODUCIBILITY :
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MainTest
{

    private static void createAndShowGUI()
    {
        //Create and set up the window.
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("why why why");
        JPanel mainPanel = new JPanel(new BorderLayout());

        /**
         * If replace JComboBox with other component like JLabel
         * There is no issue happen.
         */
        JComboBox status = new JComboBox();
        status.addItem("123");
       
//        JButton btn = new JButton("456");

        mainPanel.add(new JLabel("xxx"), BorderLayout.NORTH);
        mainPanel.add(status, BorderLayout.SOUTH);
        frame.getContentPane().add(mainPanel);

        //Display the window.
        frame.pack();
        frame.setVisible(true);

        FileOutputStream f;
        try
        {
            f = new FileOutputStream("tmp.vt");
            ObjectOutput s = new ObjectOutputStream(f);
            s.writeObject(mainPanel);
            s.flush();
            s.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private static void test()
    {
        FileInputStream f;
        try
        {
            f = new FileInputStream("tmp.vt");
            ObjectInput s = new ObjectInputStream(f);
            JPanel mp = (JPanel) s.readObject();
            JFrame frame = new JFrame();
            frame.getContentPane().add(mp);
            frame.setTitle("deserialize");
            frame.pack();
            frame.setVisible(true);
            s.close();
            f.close();
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void main(String[] args)
    {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
                test();
            }
        });
    }
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

The following facts were found out during the work on this issue:

1) This bug can be reproduced on JDK 7 starting from JDK 1.7.0-b55, which
means that the bug appeared before JDK 7u1.

2) Code changes introduced with a fix for CR ???6804747???, which were integrated
into JDK 1.7.0-b55, can be considered as a reason of this bug, since rolling
back of some changes of this fix from ???java.awt.Window??? class makes the bug
described in the current escalation disappear.
    
To complete this rollback "initGC(null);" code line should be commented out
in the method "private void initDeserializedWindow()" of the class
"java.awt.Window".

Solution for this escalation is not ready yet. Additional time is required.
                                     
2012-08-24
EVALUATION

The earlier mentioned fix for CR ???6804747 ??? just creates the conditions under which an existing bug becomes exposed. The real reason of the bug is the fact that JComboBox has ???javax.swing.AncestorNotifier??? object, which refers to a parent JFrame through ???firstInvisibleAncestor??? field, and which is assigned to all parent containers of JComboBox. During deserialization of JPanel the JFrame, which is unintentionally pulled into the whole process, is being deserialized earlier than its child JPanel and JPanel's fields are being accessed while it is not completely deseralized yet.

Sending reviewing engineers a variant of fix involving the serialization mechanism.
                                     
2012-08-28
URL:   http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/rev/84083b5de11e
User:  alexp
Date:  2012-10-24 14:35:54 +0000

                                     
2012-10-24
URL:   http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/rev/84083b5de11e
User:  lana
Date:  2012-10-26 17:26:48 +0000

                                     
2012-10-26



Hardware and Software, Engineered to Work Together