mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-15 01:42:37 +00:00
ICU-3474 serialization fix for icu4j calendar
X-SVN-Rev: 22500
This commit is contained in:
parent
a5af7ed95a
commit
0d1388172a
2 changed files with 111 additions and 16 deletions
|
@ -7,6 +7,11 @@
|
|||
package com.ibm.icu.dev.test.calendar;
|
||||
import com.ibm.icu.util.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
|
@ -1949,6 +1954,108 @@ public class CalendarRegression extends com.ibm.icu.dev.test.TestFmwk {
|
|||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* test serialize-and-modify.
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public void TestSerialization3474() {
|
||||
try {
|
||||
ByteArrayOutputStream icuStream = new ByteArrayOutputStream();
|
||||
|
||||
logln("icu Calendar");
|
||||
|
||||
com.ibm.icu.util.GregorianCalendar icuCalendar =
|
||||
new com.ibm.icu.util.GregorianCalendar();
|
||||
|
||||
icuCalendar.setTimeInMillis(1187912555931L);
|
||||
long expectMillis = 1187912520931L; // with seconds (not ms) cleared.
|
||||
|
||||
logln("instantiated: "+icuCalendar);
|
||||
logln("getMillis: "+icuCalendar.getTimeInMillis());
|
||||
icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
|
||||
logln("setSecond=0: "+icuCalendar);
|
||||
{
|
||||
long gotMillis = icuCalendar.getTimeInMillis();
|
||||
if(gotMillis != expectMillis) {
|
||||
errln("expect millis "+expectMillis+" but got "+gotMillis);
|
||||
} else {
|
||||
logln("getMillis: "+gotMillis);
|
||||
}
|
||||
}
|
||||
ObjectOutputStream icuOut =
|
||||
new ObjectOutputStream(icuStream);
|
||||
icuOut.writeObject(icuCalendar);
|
||||
icuOut.flush();
|
||||
icuOut.close();
|
||||
|
||||
ObjectInputStream icuIn =
|
||||
new ObjectInputStream(new ByteArrayInputStream(icuStream.toByteArray()));
|
||||
icuCalendar = null;
|
||||
icuCalendar = (com.ibm.icu.util.GregorianCalendar)icuIn.readObject();
|
||||
|
||||
logln("serialized back in: "+icuCalendar);
|
||||
{
|
||||
long gotMillis = icuCalendar.getTimeInMillis();
|
||||
if(gotMillis != expectMillis) {
|
||||
errln("expect millis "+expectMillis+" but got "+gotMillis);
|
||||
} else {
|
||||
logln("getMillis: "+gotMillis);
|
||||
}
|
||||
}
|
||||
|
||||
icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
|
||||
|
||||
logln("setSecond=0: "+icuCalendar);
|
||||
{
|
||||
long gotMillis = icuCalendar.getTimeInMillis();
|
||||
if(gotMillis != expectMillis) {
|
||||
errln("expect millis "+expectMillis+" after stream and setSecond but got "+gotMillis);
|
||||
} else {
|
||||
logln("getMillis after stream and setSecond: "+gotMillis);
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
errln(e.toString());
|
||||
e.printStackTrace();
|
||||
} catch(ClassNotFoundException cnf) {
|
||||
errln(cnf.toString());
|
||||
cnf.printStackTrace();
|
||||
}
|
||||
|
||||
// JDK works correctly, etc etc.
|
||||
// ByteArrayOutputStream jdkStream = new ByteArrayOutputStream();
|
||||
|
||||
// logln("\nSUN Calendar");
|
||||
//
|
||||
// java.util.GregorianCalendar sunCalendar =
|
||||
// new java.util.GregorianCalendar();
|
||||
//
|
||||
// logln("instanzieren: "+sunCalendar);
|
||||
// logln("getMillis: "+sunCalendar.getTimeInMillis());
|
||||
// sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
|
||||
// logln("setSecond=0: "+sunCalendar);
|
||||
// logln("getMillis: "+sunCalendar.getTimeInMillis());
|
||||
//
|
||||
// ObjectOutputStream sunOut =
|
||||
// new ObjectOutputStream(jdkStream);
|
||||
// sunOut.writeObject(sunCalendar);
|
||||
// sunOut.flush();
|
||||
// sunOut.close();
|
||||
//
|
||||
// ObjectInputStream sunIn =
|
||||
// new ObjectInputStream(new ByteArrayInputStream(jdkStream.toByteArray()));
|
||||
// sunCalendar = null;
|
||||
// sunCalendar = (java.util.GregorianCalendar)sunIn.readObject();
|
||||
//
|
||||
// logln("serialized: "+sunCalendar);
|
||||
// logln("getMillis: "+sunCalendar.getTimeInMillis());
|
||||
//
|
||||
// sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
|
||||
// logln("setSecond=0: "+sunCalendar);
|
||||
// logln("getMillis: "+sunCalendar.getTimeInMillis());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//eof
|
||||
|
|
|
@ -1310,9 +1310,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
|
|||
|
||||
/**
|
||||
* True if all fields have been virtually set, but have not yet been
|
||||
* computed. This occurs only in setTimeInMillis(). A calendar set
|
||||
* to this state will compute all fields from the time if it becomes
|
||||
* necessary, but otherwise will delay such computation.
|
||||
* computed. This occurs only in setTimeInMillis(), or after readObject().
|
||||
* A calendar set to this state will compute all fields from the time if it
|
||||
* becomes necessary, but otherwise will delay such computation.
|
||||
*/
|
||||
private transient boolean areFieldsVirtuallySet;
|
||||
|
||||
|
@ -1416,9 +1416,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
|
|||
|
||||
/**
|
||||
* The next available value for <code>stamp[]</code>, an internal array.
|
||||
* This actually should not be written out to the stream, and will probably
|
||||
* be removed from the stream in the near future. In the meantime,
|
||||
* a value of <code>MINIMUM_USER_STAMP</code> should be used.
|
||||
* @serial
|
||||
*/
|
||||
private transient int nextStamp = MINIMUM_USER_STAMP;
|
||||
|
@ -3968,16 +3965,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
|
|||
|
||||
/**
|
||||
* Save the state of this object to a stream (i.e., serialize it).
|
||||
*
|
||||
* Ideally, <code>Calendar</code> would only write out its state data and
|
||||
* the current time, and not write any field data out, such as
|
||||
* <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
|
||||
* and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
|
||||
* of the persistent state. Unfortunately, this didn't happen before JDK 1.1
|
||||
* shipped. To be compatible with JDK 1.1, we will always have to write out
|
||||
* the field values and state flags. However, <code>nextStamp</code> can be
|
||||
* removed from the serialization stream; this will probably happen in the
|
||||
* near future.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream stream)
|
||||
throws IOException
|
||||
|
@ -4007,6 +3994,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
|
|||
|
||||
isTimeSet = true;
|
||||
areFieldsSet = areAllFieldsSet = false;
|
||||
areFieldsVirtuallySet = true; // cause fields to be recalculated if requested.
|
||||
nextStamp = MINIMUM_USER_STAMP;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue