-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
None
-
1.2.2_006
-
x86
-
windows_nt
This problem occurs on both Solaris Sparc and Windows Platforms.
Even though the description below is Windows focused:
Customer Description:
A bug in the JDK involving dates has recently come to the forefront here. This bug is very urgent for us, as we have customers that are having significant problems because of it, and we are trying to decide what to do in the next version of our product to work around it. Here are all the details I have on this bug.
- The symptom is that, in our currenly shipping server on JDK 1.2.2, after running for a long period of time with no problems, suddenly date functions seem to become screwed up. For example, it thinks the current date is 11756980-03-16. See attached customer-output.txt for some output results from a customer's running server. At least some of the time, the change is permanent - as you can see from the output, after the bug first appears, just creating and using a Calendar object will exhibit the problem.
- It happens *very* infrequently. A server can be running fine for days, weeks or months, and then fail.
- We have only been able to replicate the problem by using the deprecated methods of java.util.Date (and its relatives java.sql.Date/Time/Timestamp). However, as noted before, sometimes when the failure occurs, subsequent uses of just the Calendar class will fail. We don't know if the bug is in the Date code, or the way Date statically caches Calendars, or in the Calendar class itself, or in the VM, or in the OS. Looking at the code for Date and Calendar, we can't figure out any bug could happen only occasionally (i.e. after working fine for a long time), unless there was a bug in the VM or OS.
- We believe that this bug is different from the one described in 4323273.
Specifically, it seems like that bug can only happen the first time that the deprecated methods on Date are used, whereas our bug seems to work fine for many iterations, and then fails.
On Windows compile the testcase DateBug.java and execute datebug.bat. This
binary will launch several times each instance creating 5 threads that
executes a test method 5000 instantiating a date object with set values
and evalutes whether the same value still exist.
if (m_sql)
date = new java.sql.Date(100, 10, 2);
else
date = new java.util.Date(100, 10, 2);
int y = date.getYear();
int m = date.getMonth();
int d = date.getDate();
// See if the data we got out is the same as the data we put in.
if (y != 100 || m != 10 || d != 2)
{
fail(date, y, m, d);
}
The result files that are created by the fail() method are in the attachments show the following differences:
result1.2.2.util.974397058754.txt
1.2.2
1.2.2
Classic VM
build JDK-1.2.2_006, native threads, symcjit
Now = Thu Nov 16 09:50:58 PST 2000
Now2 = 974397058874
Date = Thu Nov 02 00:00:00 PST 2000 [100 10 16] [100 10 2] <-------------------
Date2 = Thu Nov 02 00:00:00 PST 2000
Date3 = 2000-11-02
*******************************************************************************
result1.2.2.util.974397132870.txt
1.2.2
1.2.2
Classic VM
build JDK-1.2.2_006, native threads, symcjit
Now = Thu Nov 16 09:52:12 PST 2000
Now2 = 974397132941
Date = Thu Nov 16 09:52:12 PST 2000 [100 10 16] [100 10 16] <-------------------
Date2 = Thu Nov 02 00:00:00 PST 2000
Date3 = 2000-11-02
********************************************************************************
After further analysis the bug appears to be that sometimes GregorianCalendar.julianDayToMillis() returns the wrong value, at least on 1.2.2. You can see this by adding the below code to GregorianCalendar, just after line 1366 (on JDK 1.2.2) and compiling the testcase DateBug.java on Windows and running the datebug.bat that loops the execution of the binary.
// 973123200000L is the correct value for 2000-10-2, which is our test case.
// 1920 is the year used in SimpleDateFormat.initializeDefaultCentury() when
// we're in the year 2000, so we allow that to. All other values are errors.
if (millis != 973123200000L && year != 1920)
{
System.out.println("==========================================");
System.out.println("julianDay = " + julianDay + " millis = " + millis + " " +
Long.toHexString(millis));
System.out.println("should be = " + 2451851 + " millis = " + 973123200000L + " " +
Long.toHexString(973123200000L));
System.out.println("==========================================");
Thread.dumpStack();
System.exit(1);
}
After about five minutes similar output will appear showing the discrepancies:
OUTPUT1
==========================================
julianDay = 2451851 millis = -371084201251200000 fad9a4e292a9a400
should be = 2451851 millis = 973123200000 e292a9a400
==========================================
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:983)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:1373)
at java.util.Calendar.updateTime(Calendar.java:1311)
at java.util.Calendar.getTimeInMillis(Calendar.java:708)
at java.util.Date.<init>(Date.java:254)
at java.util.Date.<init>(Date.java:202)
at DateBug.test(DateBug.java:62)
at DateBug.run(DateBug.java:41)
OUTPUT2
D:\SUPPORT\SilverStre\DATE>java DateBug && goto loop
Filename = result1.2.2.util
==========================================
julianDay = 2440588 millis = 0 0
should be = 2451851 millis = 973123200000 e292a9a400
==========================================
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:983)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:1379)
at java.util.Calendar.updateTime(Calendar.java:1416)
at java.util.Calendar.complete(Calendar.java:979)
at java.util.Calendar.get(Calendar.java:839)
at java.util.Date.getField(Date.java:1153)
at java.util.Date.getYear(Date.java:622)
at DateBug.test(DateBug.java, Compiled Code)
at DateBug.run(DateBug.java, Compiled Code)
Even though the description below is Windows focused:
Customer Description:
A bug in the JDK involving dates has recently come to the forefront here. This bug is very urgent for us, as we have customers that are having significant problems because of it, and we are trying to decide what to do in the next version of our product to work around it. Here are all the details I have on this bug.
- The symptom is that, in our currenly shipping server on JDK 1.2.2, after running for a long period of time with no problems, suddenly date functions seem to become screwed up. For example, it thinks the current date is 11756980-03-16. See attached customer-output.txt for some output results from a customer's running server. At least some of the time, the change is permanent - as you can see from the output, after the bug first appears, just creating and using a Calendar object will exhibit the problem.
- It happens *very* infrequently. A server can be running fine for days, weeks or months, and then fail.
- We have only been able to replicate the problem by using the deprecated methods of java.util.Date (and its relatives java.sql.Date/Time/Timestamp). However, as noted before, sometimes when the failure occurs, subsequent uses of just the Calendar class will fail. We don't know if the bug is in the Date code, or the way Date statically caches Calendars, or in the Calendar class itself, or in the VM, or in the OS. Looking at the code for Date and Calendar, we can't figure out any bug could happen only occasionally (i.e. after working fine for a long time), unless there was a bug in the VM or OS.
- We believe that this bug is different from the one described in 4323273.
Specifically, it seems like that bug can only happen the first time that the deprecated methods on Date are used, whereas our bug seems to work fine for many iterations, and then fails.
On Windows compile the testcase DateBug.java and execute datebug.bat. This
binary will launch several times each instance creating 5 threads that
executes a test method 5000 instantiating a date object with set values
and evalutes whether the same value still exist.
if (m_sql)
date = new java.sql.Date(100, 10, 2);
else
date = new java.util.Date(100, 10, 2);
int y = date.getYear();
int m = date.getMonth();
int d = date.getDate();
// See if the data we got out is the same as the data we put in.
if (y != 100 || m != 10 || d != 2)
{
fail(date, y, m, d);
}
The result files that are created by the fail() method are in the attachments show the following differences:
result1.2.2.util.974397058754.txt
1.2.2
1.2.2
Classic VM
build JDK-1.2.2_006, native threads, symcjit
Now = Thu Nov 16 09:50:58 PST 2000
Now2 = 974397058874
Date = Thu Nov 02 00:00:00 PST 2000 [100 10 16] [100 10 2] <-------------------
Date2 = Thu Nov 02 00:00:00 PST 2000
Date3 = 2000-11-02
*******************************************************************************
result1.2.2.util.974397132870.txt
1.2.2
1.2.2
Classic VM
build JDK-1.2.2_006, native threads, symcjit
Now = Thu Nov 16 09:52:12 PST 2000
Now2 = 974397132941
Date = Thu Nov 16 09:52:12 PST 2000 [100 10 16] [100 10 16] <-------------------
Date2 = Thu Nov 02 00:00:00 PST 2000
Date3 = 2000-11-02
********************************************************************************
After further analysis the bug appears to be that sometimes GregorianCalendar.julianDayToMillis() returns the wrong value, at least on 1.2.2. You can see this by adding the below code to GregorianCalendar, just after line 1366 (on JDK 1.2.2) and compiling the testcase DateBug.java on Windows and running the datebug.bat that loops the execution of the binary.
// 973123200000L is the correct value for 2000-10-2, which is our test case.
// 1920 is the year used in SimpleDateFormat.initializeDefaultCentury() when
// we're in the year 2000, so we allow that to. All other values are errors.
if (millis != 973123200000L && year != 1920)
{
System.out.println("==========================================");
System.out.println("julianDay = " + julianDay + " millis = " + millis + " " +
Long.toHexString(millis));
System.out.println("should be = " + 2451851 + " millis = " + 973123200000L + " " +
Long.toHexString(973123200000L));
System.out.println("==========================================");
Thread.dumpStack();
System.exit(1);
}
After about five minutes similar output will appear showing the discrepancies:
OUTPUT1
==========================================
julianDay = 2451851 millis = -371084201251200000 fad9a4e292a9a400
should be = 2451851 millis = 973123200000 e292a9a400
==========================================
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:983)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:1373)
at java.util.Calendar.updateTime(Calendar.java:1311)
at java.util.Calendar.getTimeInMillis(Calendar.java:708)
at java.util.Date.<init>(Date.java:254)
at java.util.Date.<init>(Date.java:202)
at DateBug.test(DateBug.java:62)
at DateBug.run(DateBug.java:41)
OUTPUT2
D:\SUPPORT\SilverStre\DATE>java DateBug && goto loop
Filename = result1.2.2.util
==========================================
julianDay = 2440588 millis = 0 0
should be = 2451851 millis = 973123200000 e292a9a400
==========================================
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:983)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:1379)
at java.util.Calendar.updateTime(Calendar.java:1416)
at java.util.Calendar.complete(Calendar.java:979)
at java.util.Calendar.get(Calendar.java:839)
at java.util.Date.getField(Date.java:1153)
at java.util.Date.getYear(Date.java:622)
at DateBug.test(DateBug.java, Compiled Code)
at DateBug.run(DateBug.java, Compiled Code)
- relates to
-
JDK-4404619 Calendar nextStamp overflow
- Resolved
-
JDK-4450088 Win32: Intermittent Carry Error During 64-bit Arithmetic
- Closed