JDK-6178997 : (cal) Doc: it's not explicitly documented java.util.Calendar serialization are thread-unsafe
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: linux,windows_2000
  • CPU: x86
  • Submitted: 2004-10-14
  • Updated: 2017-02-10
Description
FULL PRODUCT VERSION :
java version "1.4.2_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)



ADDITIONAL OS VERSION INFORMATION :
The bug is not relevant to the OS. It is in the source of java.util.Calendar

A DESCRIPTION OF THE PROBLEM :
In java.util.Calendar writeObject() method, there is the following code:

	// If this Calendar has a ZoneInfo, save it and set a
	// SimpleTimeZone equvalent (as a single DST schedule) for
	// backward compatibility.
	TimeZone savedZone = null;
	if (zone instanceof ZoneInfo) {
	    SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
	    if (stz == null) {
		stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
	    }
	    savedZone = zone;
	    zone = stz;
	}

        // Write out the 1.1 FCS object.
        stream.defaultWriteObject();

	// Write out the ZoneInfo object
	// 4802409: we write out even if it is null, a temporary workaround
	// the real fix for bug 4844924 in corba-iiop
	stream.writeObject(savedZone);
	if (savedZone != null) {
	    zone = savedZone;
	}

this code is not thread safe.

there might be a race situation when two threads try to serialize the same calendar (to different streams) .

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have two threads issuing RMI requests to two different servers.

Both share one GregorianCalendar.

Breakpoint on the first just after
             if (zone instanceof ZoneInfo)

Breakpoint on the secondjust after:
	    zone = stz;

Allow the first to resume execution. The next line will abend on ClassCastException.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the calendar to be serialized to the two streams without problem
ACTUAL -
java.lang.ClassCastException: java.util.SimpleTimeZone


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassCastException: java.util.SimpleTimeZone
	at java.util.Calendar.writeObject(Calendar.java:1643)
	at sun.reflect.GeneratedMethodAccessor500.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:795)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1294)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1330)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1302)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1330)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1302)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
	at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1224)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1050)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1330)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1302)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1330)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1302)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
	at com.neat.crs.RmiCrsManagerImpl_Stub.searchProducts(Unknown Source)

REPRODUCIBILITY :
This bug can be reproduced always.
###@###.### 10/14/04 06:49 GMT

Comments
EVALUATION The Calendar class is not designed to be thread-safe at all. Please do not share a Calendar instance by multiple threads. ###@###.### 10/28/04 23:35 GMT The lack of thread-safety needs to be documented. ###@###.### 10/29/04 00:31 GMT This problem will be fixed as a documentation bug. ###@###.### 2004-12-01 01:29:41 GMT
2004-10-28