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

Calendar.get() returning incorrect values

XMLWordPrintable


      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.
       

            igerasim Ivan Gerasimov
            asaha Abhijit Saha
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: