-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
7u51
Submitter claims that their application is receiving incorrect data from
cal.get() calls. Only seen in heavy multi-threaded scenarios. This needs
further investigation.
JDBC uses the Calendar.get() call to
generate a Oracle date. The problem is when Calendar.get() is first called,
it returned wrong values. When it called again later, using the same
calendar object, it returns correct values. This happens in a stressed and
multithreaded situation. The problem goes away if I put more diagnostic
messages in the driver so it is very likely a time sensitive issue. I cannot
reproduce with standalone testcase. The issue is demonstrated in the agent QA
test environment as well as customer production environment. Tried both Sun
JDK 1.6 and 1.7 and JRockit 1.6, problem still reproduced.
The following JDBC driver code snippet demonstrated the issue:
JDBC code:
=================================================
/* If Calendar is not input, use the default one(local settings) */
if(cal == null)
cal = Calendar.getInstance();
cal.clear();
cal.setTime(timestamp);
// year returned from calendar is equivalent to an Oracle year
int year = cal.get(Calendar.YEAR);
.
//check for the ERA and set the year:Bug 1643782
if (cal.get(Calendar.ERA) == 0)
year = -(year-1);
if ((year < MINYEAR) || (year > MAXYEAR))
{
m4_throw(IllegalArgumentException, {:"Invalid year value":});
}
result[0] = (byte)(year/100 + 100);
result[1] = (byte)(year%100 + 100);
result[2] = (byte)(cal.get(Calendar.MONTH) + 1);
result[3] = (byte)(cal.get(Calendar.DATE));
result[4] = (byte)(cal.get(Calendar.HOUR_OF_DAY) + 1);
result[5] = (byte)(cal.get(Calendar.MINUTE) + 1);
result[6] = (byte)(cal.get(Calendar.SECOND) + 1);
if (result[3] == 0)
{
System.err.format("bug18130772: Thread-%d, toBytes1: %d %d %d %d %d\n",
java.lang.Thread.currentThread().getId(),
(byte) cal.get(Calendar.MONTH) + 1,
(byte) cal.get(Calendar.DATE),
(byte) cal.get(Calendar.HOUR_OF_DAY) + 1,
(byte) cal.get(Calendar.MINUTE) + 1,
(byte) cal.get(Calendar.SECOND) + 1);
.
System.err.format("bug18130772: Thread-%d, toBytes2: %d %d %d %d %d\n",
java.lang.Thread.currentThread().getId(),
cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DATE),
cal.get(Calendar.HOUR_OF_DAY) + 1,
cal.get(Calendar.MINUTE) + 1,
cal.get(Calendar.SECOND) + 1);
System.err.format("bug18130772: Thread-%d, toBytes3: %d %d %d %d %d\n",
java.lang.Thread.currentThread().getId(),
result[2],
result[3],
result[4],
result[5],
result[6]);
System.err.format("bug18130772: Thread-%d, toBytes problem reproduced
TimeStamp-%s, CAlendar-%s\n",
java.lang.Thread.currentThread().getId(), timestamp.toString(),
cal.toString());
}
=================================================
bug18130772: Thread-47, toBytes1: 2 4 17 58 14
bug18130772: Thread-47, toBytes2: 2 4 17 58 14
bug18130772: Thread-47, toBytes3: 2 0 1 1 16
bug18130772: Thread-47, toBytes problem reproduced TimeStamp-2014-02-04
08:57:15.294251,
CAlendar-java.util.GregorianCalendar[time=1391533033584,areFieldsSet=true,areA
llFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT",offset=
0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1
,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=1,WEEK_OF_YEAR=6,WEEK_OF_MONTH
=2,DAY_OF_MONTH=4,DAY_OF_YEAR=35,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,
HOUR=4,HOUR_OF_DAY=16,MINUTE=57,SECOND=13,MILLISECOND=590,ZONE_OFFSET=0,DST_OF
FSET=0]
You can see the calendar calls are made, wrong day value (0) is detected in
result[3]. The
diagnostic messages showed that calling "(byte) cal.get(XXX)" again gives
correct values (most of the time).
The same issues happened several times in a run. I have uploaded the
complete log file. The actual value of the timeStamp and Calendar object is
dumped in the diagnostic messages.
Please suggest if there is a workaround we can do in the JDBC code to get the
correct date values.