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

(timer) java.util.Timer.scheduleAtFixedRate() fails if the system time is changed

XMLWordPrintable

    • Fix Understood
    • generic, x86
    • generic, windows_nt, windows_xp

      ==per the spec of scheduleAtFixedRate():

      "It is also appropriate for for recurring activities where the total
      time to perform a fixed number of executions is important, such as
      a countdown timer that ticks once every second for ten seconds."

      This breaks if the system time is changed.

      For example,

      - a timer task is scheduled to repeat every 30 seconds

              final long PERIOD = 30 * 1000; // milliseconds
              Timer tm = new Timer();
              Date current_date = new Date() ;
              tm.scheduleAtFixedRate(task1,
      current_date,
      PERIOD) ;
              
      - then the system clock is changed (let's say, it's set back 1 minute)

      Expected: task1 is fired every 30 seconds

      Actual : task1 is not fired for 1 minute.
      (while the system clock is < current_date).
      Two executions are missed.

      Similarly, two extra executions are fired (unexpectedly) when the system clock
      is set ahead one minute after the task is scheduled using scheduleAtFixedRate().




      Name: boT120536 Date: 07/31/2001


      C:\JBuilder4\jdk1.3\bin>java -version
      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

      After a swing timer is started and before that timer is expired, a software
      tester changes the system time of the local host, say, delay the current system
      time by one day. The timer also delays its expiration time for a day.

      We dont expect the timer be delayed eventhough the current system time is
      delayed by a significant amount of time. We also do not expect the timer
      behave different if the current system time is set forward.

      I have looked at the swing Timer.java and TimerQueue.java classes, and the
      TimerQueue.java has a run() method and that calls postExpiredTimers() method.
      The postExpiredTimers() method calls the System.currentTimeMillis() to update
      the timeToWaitvariable, that is the problem. Because TimerQueue has default
      access modifier, I cannot extend it and hence I cannot override the above
      two methods. I would appreciate if you could fix this problem so that
      the Timer always fires ActionEvent as long as the predefined timeout comes
      to an end. Don't let the system time change to affect the timer's behavior.

      Regards,
      Lee Zhou
      Waterford Institute
      ###@###.###
      (Review ID: 126004)
      ======================================================================

      Name: ddT132432 Date: 11/30/2001


      D:\>java -version
      java version "1.3.1"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
      Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

      This behavior also happens in JDK1.4beta3.

      /**
       * class TimerTest
       *
       * Class used to demonstrate failure of the javax.swing.Timer after the system
       * clock has been set back.
       *
       * Steps to demonstrate bug:
       *
       * 1. Start this program running by calling its main( )
       * 2. A Frame will come up that shows the current time in a JLabel.
       * Note that the text of the JLabel is updated every second by
       * a swing timer.
       * 3. While the program is up and running, set the system clock back, for
       * example set the computer's clock back by one hour. Now notice that
       * the time is no longer being updated. That is, the op sys clock continues
       * to run and update itself, but the time read out in the java JLabel
       * is no longer updating.
       *
       * NOTE: I have also tried 1.4beta3 and still the same results.
       *
       * @author hill
       * Date: Nov 15, 2001
       * Time: 1:52:06 PM
       */
      package timertest;

      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.JLabel;
      import javax.swing.Timer;
      import javax.swing.SwingConstants;
      import java.awt.BorderLayout;
      import java.awt.Dimension;
      import java.awt.event.MouseEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.ActionEvent;
      import java.text.SimpleDateFormat;
      import java.util.TimeZone;
      import java.util.Calendar;

      public class TimerTest extends JLabel
      {
          private SimpleDateFormat dateFormat = null;
          private TimeZone defaultTimeZone = null;
          private Calendar calendar = null;
          private final String EMPTY_STRING = " ";
          private Timer timer = null;

          TimerTest( )
          {
              super( );
              setHorizontalAlignment(SwingConstants.CENTER);
              setText(EMPTY_STRING);
              setPreferredSize(new Dimension(400, 200));
              setMinimumSize(new Dimension(400, 200));
              defaultTimeZone = TimeZone.getDefault( );
              timer = new TimerTest.TimeLabelTimer( );
              timer.start( );
          }

          /**
           * Timer class that is called back at intervals to adjust the
           * seconds in time display
           */
          private class TimeLabelTimer extends Timer implements ActionListener
          {
              private final String TIME_FORMAT = " HH:mm:ss ";
              private SimpleDateFormat timeFormat = null;

              TimeLabelTimer( )
              {
                  // first param is callback interval in milliseconds
                  super(1000, null); // call back every second
                  addActionListener(this);

                  timeFormat = new SimpleDateFormat(TIME_FORMAT);
                  timeFormat.setTimeZone(defaultTimeZone);
              }

              /**
               * update the time display
               */
              public void actionPerformed(ActionEvent e)
              {
                  calendar = Calendar.getInstance(defaultTimeZone);
                  setText(timeFormat.format(calendar.getTime( )));
              }
          }

          public static void main(String[ ] args)
          {
              JFrame frame = new JFrame("Test Timer");

              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

              frame.getContentPane( ).add(new TimerTest( ), BorderLayout.CENTER);
              frame.setSize(400, 200);
              frame.pack( );
              frame.setVisible(true);
          }
      }
      (Review ID: 135746)
      ==========================================================================================================================================

      Name: ns68243 Date: 06/26/2001

      Remove SQE-lib-0121


      ======================================================================

      Name: boT120536 Date: 07/31/2001


      (Review ID: 126004)
      ======================================================================

      Name: ddT132432 Date: 11/30/2001


      Webbugs Review <--------------------------

      The users test case shows his error as expected. When changing the
      system clock, the java application froze. I have tested this test case
      on Win NT and Win 2k using 1.3.1, 1.3.1, 1.4beta3 and 1.4-rc-b87

      ###@###.### 2001-11-30
      (Review ID: 135746)
      ======================================================================
      JPE modified

      Add Yokogawa Electric in Customer Call section

      ###@###.### 2003-10-07
      =====================================================================
      JPE Modified

      Add Yokogawa another entry. thi occurs in Tiger.

      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b22)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b22, mixed mode)

      The licensee's Java product is to monitor the status of product line
      in Factory and display clock.
      To synchronize the monitor(clientPC) clock with the machine in the line,
      the system clock is adjusted periodically.
      After this synchronization, the clock seems to stop by this bug.

      They want us to fix in Tiger and backport the fix into 1.4.X.

      ###@###.### 2003-10-08
      =====================================================================
      ###@###.### 11/1/04 23:01 GMT

            Unassigned Unassigned
            hvilekar Harshad Vilekar
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: