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

(cal) Multithreaded deserialization of Calendar leads to ClassCastException

    Details

    • Subcomponent:
    • Resolved In Build:
      b51
    • Verification:
      Verified

      Description

      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

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                coffeys Sean Coffey
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: