Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7017458

(cal) Multithreaded deserialization of Calendar leads to ClassCastException

XMLWordPrintable

    • b25
    • x86, sparc
    • solaris_10, windows_vista

        FULL PRODUCT VERSION :
        java version "1.6.0_23"
        Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
        Java HotSpot(TM) Client VM (build 19.0-b09, mixed mode, sharing)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [version 6.0.6002]

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Machine running with an Intel i7 920 processor (4 physical cores with hyperthreading = 8 virtual cores)

        A DESCRIPTION OF THE PROBLEM :
        Upon deserialization of java.util.Calendar instances by multiple threads, the following exception is raised:

        java.lang.ClassCastException: java.util.SimpleTimeZone cannot be cast to sun.util.calendar.ZoneInfo
          at java.util.Calendar$1.run(Calendar.java:2653)
          at java.util.Calendar$1.run(Calendar.java:2651)
          at java.security.AccessController.doPrivileged(Native Method)
          at java.util.Calendar.readObject(Calendar.java:2650)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
          at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
          at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
          at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
          at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
          at CalendarSerialization$DeserializationThread.run(CalendarSerialization.java:80)

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        - Save the attached code in CalendarSerialization.java
        - compile with "javac CalendarSerialization.java"
        - execute with "java -cp . CalendarSerialization."

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        No error or exception should be displayed
        ACTUAL -
        One or more instances of "java.lang.ClassCastException: java.util.SimpleTimeZone cannot be cast to sun.util.calendar.ZoneInfo" are raised, with the corresponding stack trace

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.ClassCastException: java.util.SimpleTimeZone cannot be cast to sun.util.calendar.ZoneInfo
          at java.util.Calendar$1.run(Calendar.java:2653)
          at java.util.Calendar$1.run(Calendar.java:2651)
          at java.security.AccessController.doPrivileged(Native Method)
          at java.util.Calendar.readObject(Calendar.java:2650)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
          at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
          at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
          at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
          at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
          at CalendarSerialization$DeserializationThread.run(CalendarSerialization.java:80)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.io.*;
        import java.util.Calendar;

        /**
         * Test of multithreaded serialization/deserialization of Calendar.
         * @author Laurent Cohen
         */
        public class CalendarSerialization
        {
          public static void main(String[] args)
          {
            try
            {
              new CalendarSerialization().perform();
            }
            catch (Exception e)
            {
              e.printStackTrace();
            }
          }

          public void perform() throws Exception
          {
            int nbThreads = 8;
            Calendar cal = Calendar.getInstance();
            SerializationThread[] threads = new SerializationThread[nbThreads];
            for (int i=0; i<nbThreads; i++) threads[i] = new SerializationThread(cal);
            for (int i=0; i<nbThreads; i++) threads[i].start();
            for (int i=0; i<nbThreads; i++) threads[i].join();
            DeserializationThread[] threads2 = new DeserializationThread[nbThreads];
            for (int i=0; i<nbThreads; i++) threads2[i] = new DeserializationThread(threads[i].data);
            for (int i=0; i<nbThreads; i++) threads2[i].start();
            for (int i=0; i<nbThreads; i++) threads2[i].join();
          }

          public class SerializationThread extends Thread
          {
            private Calendar cal;
            public byte[] data;

            public SerializationThread(Calendar cal)
            {
              this.cal = cal;
            }

            public void run()
            {
              try
              {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(cal);
                oos.flush();
                oos.close();
                data = baos.toByteArray();
              }
              catch (Exception e)
              {
                e.printStackTrace();
              }
            }
          }

          public class DeserializationThread extends Thread
          {
            public Calendar cal;
            public byte[] data;

            public DeserializationThread(byte[] data)
            {
              this.data = data;
            }

            public void run()
            {
              try
              {
                ByteArrayInputStream bais = new ByteArrayInputStream(data);
                ObjectInputStream ois = new ObjectInputStream(bais);
                cal = (Calendar) ois.readObject();
                ois.close();
              }
              catch (Exception e)
              {
                e.printStackTrace();
              }
            }
          }
        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        I do not know of any workaround

              peytoia Yuka Kamiya (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: