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

(tz) Default timezone is incorrectly set occasionally on Linux

    Details

    • Subcomponent:
    • Resolved In Build:
      b72
    • CPU:
      x86
    • OS:
      linux
    • Verification:
      Verified

      Backports

        Description

        FULL PRODUCT VERSION :
        java version "1.5.0_06"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
        Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_06-b05, mixed mode)

          Bug also observed on 1.5.0_07.

        ADDITIONAL OS VERSION INFORMATION :
        Red Hat Enterprise Linux AS release 4 (Nahant Update 2)

        Linux 2.6.9-22.20.ELsmp #1 SMP Fri Nov 18 03:04:44 EST 2005 x86_64 x86_64 x86_64 GNU/Linux


        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Time zone is set to America/New_York, and the system time should be within the EDT period

        A DESCRIPTION OF THE PROBLEM :
        We have three identical Linux server and when we run the test case included below, the time reported by the machines are different.

        By examining the available JVM source code, I noticed that the logic that works out the default timezone on Linux is incorrect.

        The way JVM works out the default timezone is as follows:

        1) Looks to environment variable TZ
        This is not set in our linux box

        2) JVM looks for the file /etc/sysconfig/clock and tries to find the "ZONE" entry.

        However, on these host the ZONE entry does not have a double quote around the actual variable, and the JVM code is unable to recongise the entry.

        3) If the ZONE entry is not found, the JVM will compare contents fo /etc/localtime with the contents of every file in /usr/share/zoneinfo recursively. When the contents matches, it returns the path and filename, referenced from /usr/share/zoneinfo

        On our machine, there are three files in /usr/share/zoneinfo that matches /etc/localtime (these files are standard on RHEL4 machines):

        /usr/share/zoneinfo/America/New_York
        /usr/share/zoneinfo/posixrules
        /usr/share/zoneinfo/EST5EDT

        What happens is that depends on the way OS transverse the filesystem, the name that JVM get can be different. On the box that fail the test, the jvm actually found posixrules file first, which means that the JVM thinks the timezone is "posixrules". The JVM will then attempt to look up timezone mapping in <java.home>/jre/lib/zi directory, and it will fail the find the timezone. So it will revert to the default GMT+offset timezone id as a fail safe, which does not take into the account for daylight saving.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        We have three identical Linux server and ran the test case included below, the time reported by the machine is different.

        (host 1)
        bash-3.00$ date ; /opt/sunjava-1.5.0_06/jre/bin/java simpleTest
        Tue Aug 1 14:43:25 EDT 2006
        Simple test Josh

         TIME ZONE :GMT-05:00
        Value of milliseconds since Epoch is 1154457805659
        Value of s in readable format is Tue Aug 01 13:43:25 GMT-05:00 2006

        (host 2)
        bash-3.00$ date ; /opt/sunjava-1.5.0_06/jre/bin/java simpleTest
        Tue Aug 1 14:43:36 EDT 2006
        Simple test Josh

         TIME ZONE :Eastern Standard Time
        Value of milliseconds since Epoch is 1154457816528
        Value of s in readable format is Tue Aug 01 14:43:36 EDT 2006

        Notice that the default timezone returned by the systems are different.


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The testcase should show the same time in readable format (like host 2)
        ACTUAL -
        During EDT, the printed time could be different from what we are expecting

        REPRODUCIBILITY :
        This bug can be reproduced occasionally.

        ---------- BEGIN SOURCE ----------
        import java.util.*;
        import java.text.*;
        class simpleTest
        {
                public static void main(String args[])
                {
                   System.out.println("Simple test Josh ");

                   Date now = new Date();
                   DateFormat df = DateFormat.getDateInstance();
                        Calendar cal = Calendar.getInstance();
                System.out.println("\n TIME ZONE :"+ cal.getTimeZone().getDisplayName());
                   long nowLong = now.getTime();
                   String s = now.toString();
                   System.out.println("Value of milliseconds since Epoch is " + nowLong);
                   System.out.println("Value of s in readable format is " + s);

                }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        1) Set TZ to the correct timezone
        2) pass -Duser.timezone with the correct timezone
        3) make sure /etc/sysconfig/clock ZONE variable has quote around the value

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  peytoia Yuka Kamiya (Inactive)
                  Reporter:
                  ndcosta Nelson Dcosta (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  1 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Imported:
                    Indexed: