Debian GNU/Linux

Java reports time zone incorrectly during CDT (US Daylight saving time)

Reported by Allen Crider on 2006-06-08
74
This bug affects 5 people
Affects Status Importance Assigned to Milestone
sun-java5 (Debian)
New
Unknown
sun-java5 (Ubuntu)
Low
Unassigned
Nominated for Dapper by Markus Strohmeier
Nominated for Hardy by Markus Strohmeier
Nominated for Intrepid by Markus Strohmeier
Nominated for Jaunty by Markus Strohmeier
Nominated for Karmic by Markus Strohmeier
Nominated for Lucid by Markus Strohmeier
sun-java6 (Ubuntu)
Undecided
Unassigned
Nominated for Dapper by Markus Strohmeier
Nominated for Hardy by Markus Strohmeier
Nominated for Intrepid by Markus Strohmeier
Nominated for Jaunty by Markus Strohmeier
Nominated for Karmic by Markus Strohmeier
Nominated for Lucid by Markus Strohmeier

Bug Description

Binary package hint: sun-java5-bin

The following source code (provided to me by a developer on the FreeGuide-TV project) demonstrates the problem:

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class TimeTester
{

    public static void main( String[] args )
    {
        Calendar calendar = new GregorianCalendar();
        Date trialTime = new Date();
        calendar.setTime(trialTime);

        System.out.println("ZONE_OFFSET: " + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000)));

        System.out.println("DST_OFFSET: " + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000)));
    }

}

When run using Sun Java, the DST_OFFSET is 0, even though my time zone is currently at Central Daylight Time so it should be 1. I also tried alternatives to Sun Java. Blackdown Java has the same problem, but GNU Java and Kaffe produce the correct results. Unfortunately, Sun Java is the only package that has been able to run FreeGuide-TV for me so far, which is what I was using when I discovered this bug.

description: updated
TLE (k-nielsen81) wrote :

Obviously I cannot reproduce this at the current time (since it involves daylight saving) but I have been searching the Java bugtracker to try and see if I could find it reported there. Unfortunately there are quite a few bug that may or may not be related. It is difficult for me to determine since I'm not that adept at Java.

I would advice the original reporter or the developers that found the bug to do the following:
1. Try to determine of there is any reason to believe that this should be related to this distribution. e.g. does either of the classes involved, use any methods outside Java to determine the timezone, like say the system date or something of a sort. This could be supplemented by testing the code on another distro.
2. If it turn out that this is purely a internal Java issue. Then go upstream and see if you can figure out if this bug has already been filed there. If it hasn't the file it and link to it in this thread.

During my searches I found out that there are some "similar" bug reported in the TimeZone class. But I couldn't quite figure out if that class is being used by the GregorianCalender.

The Java bug tracker searcher is here: http://bugs.sun.com/bugdatabase/index.jsp
and if searched with keywords like calender DST it returns the following hits: http://bugs.sun.com/bugdatabase/search.do?process=1&category=&bugStatus=&subcategory=&type=bug&keyword=calender+dst
Happy hunting

Mark Reitblatt (mark-reitblatt) wrote :

Seems to work for me here. Setting the date to June 1, 1997 as a test case worked. 2006/06/08 (date this was filed) works as well. Considering how long this has sat open with no attention, and my inability to reproduce the problem, I'm going to close the bug report.

If you feel this is in error and can provide a specific example (date) where Dapper/Feisty's Sun Java doesn't work, then please reopen the bug report.

Changed in sun-java5:
importance: Undecided → Low
status: Unconfirmed → Needs Info
status: Needs Info → Rejected

I can still reproduce this. I'm really sorry, but I've done it on an Edgy system, just to be difficult. I'd be really surprised if it's not the same on both Dapper and Feisty.

balaaman@pingu:~/cvs/java-test$ java -version
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)

balaaman@pingu:~/cvs/java-test$ cat TimeTester.java
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class TimeTester
{

            public static void main( String[] args )
                        {
                                        Calendar calendar = new GregorianCalendar();
                                                Date trialTime = new Date();
                                                        calendar.setTime(trialTime);

                                                                System.out.println("ZONE_OFFSET: " + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000)));

                                                                        System.out.println("DST_OFFSET: " + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000)));
                                                                            }

}

balaaman@pingu:~/cvs/java-test$ javac TimeTester.java
balaaman@pingu:~/cvs/java-test$ date
Wed Mar 7 10:33:36 GMT 2007
balaaman@pingu:~/cvs/java-test$ java TimeTester
ZONE_OFFSET: 0
DST_OFFSET: 0
balaaman@pingu:~/cvs/java-test$ sudo date 060110331997
Password:
Sun Jun 1 10:33:00 BST 1997
balaaman@pingu:~/cvs/java-test$ date
Sun Jun 1 10:33:02 BST 1997
balaaman@pingu:~/cvs/java-test$ java TimeTester
ZONE_OFFSET: 0
DST_OFFSET: 0

I would expect the final line above to read: DST_OFFSET: 1

Right?

Thanks, Andy

Re-opening since I can still reproduce. Please show what you did differently to make this not happen.

Changed in sun-java5:
status: Rejected → Unconfirmed
Mark Reitblatt (mark-reitblatt) wrote :

Happily. I'm in time zone CST, and I ran the following code:

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class TimeTester
{

    public static void main( String[] args )
    {
        Calendar calendar = new GregorianCalendar(106 + 1900, 6, 8);
// Date trialTime = new Date();
// calendar.setTime(trialTime);

        System.out.println("ZONE_OFFSET: " + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000)));

        System.out.println("DST_OFFSET: " + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000)));
    }

}

Which printed out:
ZONE_OFFSET: -6
DST_OFFSET: 1

Changed in sun-java5:
status: Unconfirmed → Needs Info

You are explicitly setting the time in the constructor for GregorianCalendar. Do you get the same results when you set your system date and then use the default constructor for GregorianCalendar?

Changed in sun-java5:
status: Needs Info → Unconfirmed
Mike Green (mikey-badpenguins) wrote :

The reason it reports an incorrect time zone is because sun java uses its own time zone database. As far as I can tell anything below 1.6 needs to be patched for the upcoming DST changes. I have had to run the timezone updater from Sun since no backports have been made available. An awful lot of people who run java apps are in for a surprise on March 11th.

The timezone updater is documented here:

http://java.sun.com/javase/tzupdater_README.html

You have to register to download it. Installing the patch will, of course, overwrite files installed by the original package, which is never a good thing. Until a backport becomes available I have no other option....

Mike Green (mikey-badpenguins) wrote :

Here is a link to a page with some validation code:

http://www.theserverside.com/tt/articles/article.tss?l=CountdownDST2007

Jason Harley (jharley) wrote :

I've run the timezone updater as well, to fix my local JVM's zone database but the package really should be synchronized with Sun's latest 1.5.X release (which does have proper DST values).

Note that I am not in the US, so should not be affected by the US foobar. Java fails to report DST as 1 when my system clock is set to summer, and I am in the UK (UTC and British Summer Time).

Christian Assig (chrassig) wrote :

I am also affected by this bug in continental Europe. I have two Kubuntu installations, one is an edgy installation with sun-java5, the other one is feisty with sun-java6.

I tried the sample application DateTest from
http://www.javaworld.com/javaworld/jw-10-2003/jw-1003-time.html

Edgy with Java 5 shows the correct time (currently GMT offset +1 and dstSavings +1) and the correct time zone "id=Europe/Amsterdam"

Feisty with Java 6 however is affected by this bug (or at least a bug very similar to this one). The time is off by one hour because the DST savings are not taken into account. Java by default uses a time zone called "id=GMT+01:00" instead of "id=Europe/Amsterdam". "id=GMT+01:00" obviously does not include any DST savings. I can manually override the time zone by executing

java -Duser.timezone=Europe/Amsterdam DateTest

instead of simply java DateTest

So somehow Java 6 under feisty is getting the wrong time zone from the system. I checked /etc/timestamp, which correctly reads "Europe/Amsterdam", and date also reports the correct time. I switched to time zone America/Chicago using KDE's application for setting the time and time zone, but the time zone in Java changed to "id=GMT-06:00", not to "id=America/Chicago" as it should.

Christian Assig (chrassig) wrote :

Another workaround is to set the environment variable TZ (for time zone obviously), e.g. by executing
export TZ=`cat /etc/timezone`

If TZ is set, Sun's Java always uses its value under Linux.
See http://minaret.biz/tips/timezone.html

Christian Assig (chrassig) wrote :

Something seemed to be wrong with /etc/localtime in my case.

The following solved the problem on my feisty machine:

sudo cp /etc/localtime /etc/localtime.bak
sudo ln -s -f /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

See http://ubuntuforums.org/showthread.php?p=2312649

Note however that my old /etc/localtime is binary identical to /usr/share/zoneinfo/Europe/Amsterdam. So it looks to me like Java expects to find a symbolic link here, and the time zone detection fails if Java encounters a regular file instead of the link.

This solution also works for me (creating a link to
/usr/share/zoneinfo/US/Central in my case). I originally reported this
bug against Dapper, but it seemed to go away with Edgy (DST was not in
effect when I installed Edgy and the problem did not appear when DST
started in March). However, it returned when I installed Feisty beta
recently, and it didn't matter whether I used sun-java5 or sun-java6.

Thanks for this solution. It will at least allow me to use the
applications that depend on it until a better solution is provided.

Allen Crider

Christian Assig wrote:
> Something seemed to be wrong with /etc/localtime in my case.
>
> The following solved the problem on my feisty machine:
>
> sudo cp /etc/localtime /etc/localtime.bak
> sudo ln -s -f /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
>
> See http://ubuntuforums.org/showthread.php?p=2312649
>
> Note however that my old /etc/localtime is binary identical to
> /usr/share/zoneinfo/Europe/Amsterdam. So it looks to me like Java
> expects to find a symbolic link here, and the time zone detection fails
> if Java encounters a regular file instead of the link.
>

Christian Assig (chrassig) wrote :

Setting to confirmed because Allen can reproduce the behaviour

Changed in sun-java5:
status: Unconfirmed → Confirmed
Changed in sun-java6:
status: Unconfirmed → Confirmed
Christian Assig (chrassig) wrote :

I updated my edgy installation with sun-java5 to feisty with sun-java6 after feisty 's final release. This machine is still not affected by this bug.

My other machine now shows the wrong time and time zone again, probably because the symbolic link was overwritten during a package upgrade with a regular file.

I have found out that even without the symbolic link, Java detects the time and time zone correct when I choose a time zone that has no DST at the moment, e.g. Australia/Perth or Asia/Shanghai.

Unfortunately, I don't know yet what the difference between the two installations causing this bug might be. I already did a directory diff on the /etc/java and /etc/java-6-sun folders of both system, but they are identical. /etc/localtime is identical on both machines as well. Any hints regarding what else I could compare would be appreciated.

Mike Green (mikey-badpenguins) wrote :

Please read http://java.sun.com/developer/technicalArticles/Intl/USDST_Faq.html, particularly question 9. The local timezone database, localtime links, and the TZ environment variable do not have anything to do with the problem (according to Sun).

Allen Crider (acrider77) wrote :

Mike Green wrote:
> Please read
> http://java.sun.com/developer/technicalArticles/Intl/USDST_Faq.html,
> particularly question 9. The local timezone database, localtime links,
> and the TZ environment variable do not have anything to do with the
> problem (according to Sun).
>
That doesn't quite make sense. Java may have its own copy of the
timezone database, but it must use something from the user or system to
determine the timezone on the machine where it is running. And given
the behavior we've seen, my guess is that it uses the environment
variable TZ if it is set or the /etc/localtime file in some manner
otherwise. Or it may be using another library that depends on those to
determine the timezone. I haven't had the time to try to track down the
Java source code and determine what it uses and I'm afraid I'm not going
to be able to anytime soon.

Allen Crider

Mike Green (mikey-badpenguins) wrote :

> That doesn't quite make sense. Java may have its own copy of the
> timezone database, but it must use something from the user or system to
> determine the timezone on the machine where it is running.

It makes sense if you consider that jvm's run on many platforms that handle timezone information in their own way. Perhaps there are individual java classes/methods that use the host o/s timezone environment. From what I am seeing in that Sun FAQ, you can't depend on that, which is why they provide the tzupdater tool. Basically the embed a local copy of the official timezone database. You also have to consider that there might be multiple copies of jre/jdk's running on individual machines.

All I know is that even after successfully updating my timezone database java was still not functioning correctly, I have to run the tzupdater tool every time.

Mike Green (mikey-badpenguins) wrote :

Well, since it appears that the sun java package is not going to be updated for dapper users, I might as well post my workaround. The sun tzupdater package requires a registered account to download it, and I have no idea what licensing restrictions it is distributed under. I created this package to update all of my servers.

1) download the tzupdater zip archive from http://java.sun.com/javase/tzupdater_README.html
2) Extract the attached debian source package: tar xvfz sun-java5-tzupdater.tar.gz
3) Move the downloaded zip file into the extracted directory: mv tzupdater-*.zip sun-java5-tzupdater
4) Edit sun-java5-tzupdater/debian/rules, set ZDIR and ZIP to match your downloaded zip file.
5) Build the package:
 cd sun-java5-tzupdater
 dpkg-buildpackage -b -rfakeroot

You now have a deb package in the parent directory. Installing it on a box that already has the dapper provided sun java package will update the currently installed java timezone database. The sun tzupdater alters the already existing package, so any updates or reinstalls of the original dapper package will require the updater to be reinstalled. The postinst detects if java is present and if the currently installed java even needs updating...

Christian Assig (chrassig) wrote :

I have had a look at the Java source code. It took me about 30 minutes to find the right file and analyse its behaviour.
The time zone detection for Linux is implemented in j2se/src/solaris/native/java/util/TimeZone_md.c

Java looks at the environment variable TZ first.
If it is not set, it reads /etc/sysconfig/clock.
If it does not find the file or a value for TZ in the file, it continues by examining /etc/localtime.
If /etc/localtime is a symbolic link, the timezone is derived from the destination of the link.
If /etc/localtime is a regular file, Java reads all the files in /usr/share/zoneinfo and tries to find a file that is identical to /etc/localtime. If a file is found, the time zone is derived from the path of the file.

I have found out that in my case, Europe/Amsterdam in /usr/share/zoneinfo is identical to /etc/localtime, and in addition there is a symbolic link called localtime pointing to /etc/localtime in /usr/share/zoneinfo. After deleting the symbolic link /usr/share/zoneinfo/localtime, Java detects the time zone correctly on all systems. So I guess whether or not this bug appears depends on the order in which Java cycles through the files in /usr/share/zoneinfo. If it finds the symbolic link to /etc/localtime first, the detection fails because the time zone cannot be derived from the path /usr/share/zoneinfo/localtime. If it finds the regular time zone file first, the detection succeeds.

Possible ways to solve this bug that I could imagine would be to remove /usr/share/zoneinfo/localtime (but it is probably needed by other applications/libraries), to get the files in /usr/share/zoneinfo in the correct order (bad) or implement a check in j2se/src/solaris/native/java/util/TimeZone_md.c if the file /usr/share/zoneinfo/localtime is a regular file and to skip all symbolic links.

Allen Crider (acrider77) wrote :
Download full text (3.2 KiB)

Christian Assig wrote:
> I have had a look at the Java source code. It took me about 30 minutes to find the right file and analyse its behaviour.
> The time zone detection for Linux is implemented in j2se/src/solaris/native/java/util/TimeZone_md.c
>
> Java looks at the environment variable TZ first.
> If it is not set, it reads /etc/sysconfig/clock.
> If it does not find the file or a value for TZ in the file, it continues by examining /etc/localtime.
> If /etc/localtime is a symbolic link, the timezone is derived from the destination of the link.
> If /etc/localtime is a regular file, Java reads all the files in /usr/share/zoneinfo and tries to find a file that is identical to /etc/localtime. If a file is found, the time zone is derived from the path of the file.
>
> I have found out that in my case, Europe/Amsterdam in
> /usr/share/zoneinfo is identical to /etc/localtime, and in addition
> there is a symbolic link called localtime pointing to /etc/localtime in
> /usr/share/zoneinfo. After deleting the symbolic link
> /usr/share/zoneinfo/localtime, Java detects the time zone correctly on
> all systems. So I guess whether or not this bug appears depends on the
> order in which Java cycles through the files in /usr/share/zoneinfo. If
> it finds the symbolic link to /etc/localtime first, the detection fails
> because the time zone cannot be derived from the path
> /usr/share/zoneinfo/localtime. If it finds the regular time zone file
> first, the detection succeeds.
>
> Possible ways to solve this bug that I could imagine would be to remove
> /usr/share/zoneinfo/localtime (but it is probably needed by other
> applications/libraries), to get the files in /usr/share/zoneinfo in the
> correct order (bad) or implement a check in
> j2se/src/solaris/native/java/util/TimeZone_md.c if the file
> /usr/share/zoneinfo/localtime is a regular file and to skip all symbolic
> links.
>

Given the above information, I see three other possible solutions:
1. Add a check in TimeZone_md.c to have the second or third check be an
attempt to read /etc/timezone (I don't like this because I'd rather not
have Ubuntu specific modifications to the Java source if possible)
2. Modify whichever package(s)/program(s) currently copies the timezone
file to /etc/localtime to create a symbolic link instead (I see no
reason why this should be a problem; I've encountered no problems as a
result of replacing the file with a symbolic link manually)
3. Modify the same package(s)/program(s) to create /etc/sysconfig/clock
(I don't like this as well as 2 simply because I hate to see another
directory added to /etc just to satisfy Sun Java when there is a better
solution)

After a little searching, at least one program that would need to be
modified if solution 2 or 3 is adopted is /usr/sbin/tzconfig. Another
thing that should be looked at is the installation scripts for the
package tzdata, as it was an update to that package that recently
removed the link I had created manually and forced me to recreate it.
And I don't know whether all of the GUI administration tools that allow
a user to change the timezone are wrappers around tzconfig or if they
have another method ...

Read more...

Mike Green (mikey-badpenguins) wrote :

Look guys, according to sun (http://java.sun.com/developer/technicalArticles/Intl/USDST/):

"NOTE: The Java platform's time zone data is completely independent from your operating system's time zone data. Therefore, you do not need to update your operating system for the Java platform to work correctly."

From everything I have read it appears that after 1.4.0, java uses its own internal olson database. It seems to me you might be barking up the wrong tree by looking into utility classes and such... Why not just take a look at what Sun is saying you have to do to fix the problem?

Christian Assig (chrassig) wrote :

@Mike
You have to read Sun's statement you are quoting correctly. What it means: You do not have to update data about the time zones, such as when DST begins and ends, in your operating system. But Java detects the time zone you are in the way I have described it. That's what I could see in the sources, and that's also exactly the behaviour I could reproduce. Let me clarify again what Sun's statement means: When a country decides to change the way it handles DST (such as Western Australia did last year or the U.S. did this year), you get these changes about the DST attributes of your time zone into your Java virtual machine by updating Java, you do not have to update your operating system's time zone database. But this can only work if the Java VM knows in which time zone it is, which it does in the way I have described.

@Allen
Solution 2 may be a problem. The reason for /etc/localtime not being a link is that /usr/share/zoneinfo might be mounted from a different partition than /etc. So it may be possible at boot time that a program wants to read /etc/localtime before /usr/share/zoneinfo is mounted, which would fail if /etc/localtime is a symbolic link to /usr/share/zoneinfo.

Regarding solutions 2 and 3: I already tried to rename /usr/sbin/tzconfig. KDE's time configuration tool is still able to change the time zone if /usr/sbin/tzconfig does not exists, so unfortunately it does not suffice just to change /usr/sbin/tzconfig, at least the KDE code would have to be changed, probably other packages as well.

Allen Crider (acrider77) wrote :
Download full text (4.7 KiB)

I should have thought about the possibility of having
/usr/share/zoneinfo on a different partition. And I had doubts about
changing tzconfig being a good solution as it did not appear to be easy
to wrap. It would be much easier (at least for me) to reproduce the
needed functionality in whatever programming language an application was
written in than wrapping tzconfig.

I'm beginning to believe there is not going to be a nice long-term
solution to this problem unless Sun changes their code. As I see it
right now, we're coming down to just a few somewhat practical solutions,
all with drawbacks:

1. Modify the source for sun-java, either to add a new rule to look for
the file /etc/timezone if TZ is not set or to modify the way the rule
for /etc/localtime being a regular file works. If Sun were to
incorporate this change into their source, it would be the best
solution, but I don't like it otherwise. This probably comes down to
whether Ubuntu is handling time zones differently than other Linux
distributions (I haven't run any other distributions since installing
Breezy and don't remember how others did it before), and if so, whether
it is big enough for Sun to incorporate an Ubuntu specific fix.

2. Modify the installation script(s) for sun-java to provide one of the
things being looked for. That would probably come down to to either
creating the file /etc/sysconfig/clock or globally setting TZ. Since
I've never looked at /etc/sysconfig/clock (it doesn't exist on any of my
current systems), I don't know if that could be done in a manner that
wouldn't break the next time the user changed time zones, although I
doubt if many users do that very often. And I really haven't kept up
with whether there is a standard way for setting an environment variable
for all users. The way I would have done this in the past would have
been to add it to /etc/bash.bashrc or a similar file. This has the
disadvantage that it could possibly be lost the next time an update
replaced /etc/bash.bashrc.

3. Change the name of the java executable and create a wrapper script
that would set needed environment variables.

4. Modify applications that use this feature to work around it. For
example, the only application I use that has been affected by this bug
is FreeGuide. TZ could be set in the script /usr/bin/freeguide. I'm
not crazy about this solution, but it should work. OTOH, I don't know
what impact this might have on users that are using a different JVM.
However, the last time I tried (when I first discovered this bug on
Dapper), I was unable to get FreeGuide to run at all with any other
available JVM. I still can't get it to work with GCJ, but I haven't
tried installing any other JVMs.

I wish I had a better idea, but I can't think of anything else that
would work for everyone. For now, I can live with manually replacing
/etc/localtime with a link, although if it isn't solved, I'll probably
fall back on adding TZ to my .bashrc (workable on my personal system
that doesn't have any other users). Someone else will have to decide
whether it is a big enough problem for other users to implement a system
level fix.
...

Read more...

Mike Green (mikey-badpenguins) wrote :

>You have to read Sun's statement you are quoting correctly. What it means:
>You do not have to update data about the time zones, such as when DST begins
>and ends, in your operating system. But Java detects the time zone you are in
>the way I have described it. That's what I could see in the sources, and that's

Ah, thanks for the clue stick Christian. It looks like this bug needs to be split into two, one dealing with how java determines what timezone the host is running in, another for how java deals with it internally. Even if you do find a solution to the localtime/TZ problem, the original bug will still be present if the internal java olson database is not corrected. I don't have a problem on my servers determining the correct timezone because the glibc timezone database is corrected for DST, my problem is the sun java vm distributed in dapper does not know about the DST changes. It is my impression that this bug is about the java olson database needing an update... If my impression is wrong should I file another bug?

Allen Crider (acrider77) wrote :

Mike Green wrote:
>> You have to read Sun's statement you are quoting correctly. What it means:
>> You do not have to update data about the time zones, such as when DST begins
>> and ends, in your operating system. But Java detects the time zone you are in
>> the way I have described it. That's what I could see in the sources, and that's
>
> Ah, thanks for the clue stick Christian. It looks like this bug needs
> to be split into two, one dealing with how java determines what timezone
> the host is running in, another for how java deals with it internally.
> Even if you do find a solution to the localtime/TZ problem, the original
> bug will still be present if the internal java olson database is not
> corrected. I don't have a problem on my servers determining the correct
> timezone because the glibc timezone database is corrected for DST, my
> problem is the sun java vm distributed in dapper does not know about the
> DST changes. It is my impression that this bug is about the java olson
> database needing an update... If my impression is wrong should I file
> another bug?
>
It sounds like we need to divide this into two bugs. My problem has a
lot more to do with the localtime/TZ situation.

Allen

Mike Green (mikey-badpenguins) wrote :

>It sounds like we need to divide this into two bugs. My problem has a
>lot more to do with the localtime/TZ situation.

As far as the localtime/TZ situation, why not just handle it during the install of the jdk/jre? Determine if /etc/localtime is a link or not and warn the user that they need to copy over whatever localtime is linked to if they have a separate mount for /usr, or set TZ somewhere...

Christian Assig (chrassig) wrote :

> It sounds like we need to divide this into two bugs. My problem has a
> lot more to do with the localtime/TZ situation.
I agree. Because of the title of this bug, I suggest we keep track of the time zone detection in this bug, and someone reports a new bug for the problem regarding deprecated time zone data in Java's time zone database.

> As far as the localtime/TZ situation, why not just handle it during the install of the jdk/jre?
Pretty simple: A lot of people have Ubuntu on their laptops and travel from time zone to time zone (like me e.g.). By just determining the time zone during the package installation, Java would not be updated once you change the time zone settings of the operating system, at least not until you install a new Java package.

> Determine if /etc/localtime is a link or not and warn the user that they need to copy over whatever localtime is linked to if they have a separate mount for /usr, or set TZ somewhere...
As described above, this does not work either. If you change /etc/localtime to a symbolic link during the installation of the Java package, it might be changed back by any program included in Ubuntu that makes any kind of changes to the time zone settings. If /etc/localtime is a regular file (that is the current situation), you may encounter the bug described here.

Some thoughts about Allen Crider's suggestions from 2007-05-05:

1. The time zone detection already checks if /etc/localtime is a regular file or a symbolic link, so why not make it check if the files in /usr/share/zoneinfo are regular files? Of course, this could cause trouble if someone decides to change all files in /usr/share/zoneinfo to symbolic links for some reason. Simply reading /etc/timezone if it exists would be my personal favourite.

2. Like I said before, I guess there are quite a lot of people using Ubuntu on laptops that change time zones quite often. So I think if you want to change the Ubuntu environment to make Sun's current implementation detect the time zone correctly, you will have to change all applications in Ubuntu that modify time zones to either set the environment variable TZ or to create /etc/sysconfig/clock as well. Setting TZ during boot time would not suffice, as you would have to reboot every time you change the time zone setting.

3. Very ugly, but it could work. Like I wrote before, you would have to put something like
export TZ=`cat /etc/timezone`
into the wrapper scripts for all java VM executables.

4. A Java VM is supposed to know the correct time and time zone, and it should not be the duty of any single Java based application to implement a workaround. So I guess this is just a workaround, not a bug fix at all.

Christian Assig (chrassig) wrote :

A similar bug has already reported at Sun. It is marked as being in progress, but I have no idea how long it might take until Sun takes care of it.

See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6456628

Another fix for this bug might be to rewrite the scanning of /usr/share/zoneinfo to continue if a file is found that is identical to /etc/localtime, but whose name does not correspond to a time zone known to Java.

Joe Kislo (joe-k12s) wrote :

People were mentioning writing the correct timezone information to /etc/sysconfig/clock aswell as an option, here is the format:
ZONE="America/New_York"
UTC=false
ARC=false

This doesn't seem like such a horrible idea. There may be even other (non-ubuntu pieces of software) that use the /etc/sysconfig/clock file that may benefit from this.

I use java pretty extensively on ubuntu servers/workstations, but I don't use the ubuntu packages, and I am affected by this issue aswell. I would have to recommend *against* changing the java source code to fix this issue... The average end-user probably doesn't care if they run an ubuntu modified version of java, or what SR of the 1.5.0 JVM they are running. But coming from a server environment, we are very closely tied to a version of java, right down to the SR and build number. Any JVM changes need to go through pretty extensive hardening; and as a result, we don't tie our JVM to a distro (also we have servers running different distros aswell). I also have over 10 different jvms installed on my workstation, and I flip between atleast 3 of those pretty regularly (i586, amd64, 1.6.0). It seems like the best solution is going to be one that works for JVMs out of the box, since I would guess most server environments are going to be seeing a non-ubuntu JVM on the system.

As far as I can tell, what timezone java thinks is correct appears to be random per machine (a quick check of 10 workstations appears to find a high level of variance depending on what ubuntu release they are running, if they were upgraded from older releases, and what architecture they are running).

I would strongly recommend a solution be found, and not wait for sun to save the day (which I've done in the past with not much luck). I don't have these problems on my redhat servers. Java is a very common server application, and it should really *work* on ubuntu servers, even if that means living with a non-ideal workaround (EG: writing out /etc/sysclock/config) for a few releases.

Matthias Klose (doko) wrote :

Joe Kislo schrieb:
> I would strongly recommend a solution be found,
[...]

sure, you can recommend that, but read the license what a distributor is allowed
to do, and attach a patch which fixes the problem and is conforming to the license.

Joe Kislo (joe-k12s) wrote :

Matthias:

Are you referring to what a distributor can do for sun's JVM? The solution I have put onto my ubuntu servers would require no changes to Java. It would probably require changing tzconfig to write the timezone out to a second place (/etc/sysconfig/clock)

Changed in sun-java5:
status: Unknown → New
Arik Kfir (arikkfir) wrote :

I'm not familiar with the internals of the JVM, but why does a JVM even need its own database? Why can't it use the native OS's timezone database, just like it abstracts many other OS services.

Although I'm a Java programmer, I firmly believe that managing the time zone information is the system administrator job, since it interacts with many other services and processes on the system (cron, backups, etc).

Would patching the JVM to make it use Ubuntu's native time-zone database be a daunting task, in your opinion? (I'm asking because I'm not at all familiar with the actual JVM source code)

Allen Crider (acrider77) wrote :

Arik Kfir wrote:
> I'm not familiar with the internals of the JVM, but why does a JVM even
> need its own database? Why can't it use the native OS's timezone
> database, just like it abstracts many other OS services.
>
> Although I'm a Java programmer, I firmly believe that managing the time
> zone information is the system administrator job, since it interacts
> with many other services and processes on the system (cron, backups,
> etc).
>
> Would patching the JVM to make it use Ubuntu's native time-zone database
> be a daunting task, in your opinion? (I'm asking because I'm not at all
> familiar with the actual JVM source code)
>
I haven't looked at much of the JVM source, so I have no idea how
difficult this would be. I would object to doing it just because I
wouldn't expect the Ubuntu team to have to maintain a patch specific to
Ubuntu. I would want any changes made to go into the Sun code where it
would be maintained as part of the upstream version of the JVM. And as
Java is supposed to be cross-platform and provide better security, there
may be a good reason for it not depending on the operating system for
the timezone database.

However, I don't know whether such a change would fix the problem I
reported anyway. The problem I have is that the JVM is sometimes unable
to determine which time-zone it is in. I figured out at one time what
the algorithm was that the JVM uses to determine the correct time-zone,
and it wouldn't work consistently with Ubuntu/Kubuntu, at least not
while DST was in effect. For now, I've gotten around the problem by adding
 export TZ=`cat /etc/timezone`
to /etc/profile. I'm not convinced that that is a good solution, but
there are problems with every other solution that has been suggested.

Allen Crider

Arik Kfir (arikkfir) wrote :

Allen Crider wrote:
> I would want any changes made to go into the Sun code where it
> would be maintained as part of the upstream version of the JVM.
Yes, you are right. I was only asking because I thought maybe it would be a small patch, which Ubuntu manages quite a few, in which case it would not be too unusual. If it's a major undertaking - I agree full heartedly.

> And as Java is supposed to be cross-platform and provide better
> security, there may be a good reason for it not depending on the
> operating system for the timezone database.
I'm afraid I don't agree with that - the Java platform does not guarantee EXACT runtime results regardless of the platform - they (JVM architects) are not naive and we all know that there are, and always will be, differences. For example, the Java2D module uses DirectX on Windows, and OpenGL or X11 on Linux/UNIX. This is a rational design - all operating systems provide pretty much the same set of services, only in different APIs - Java simply wants to abstract these different APIs, and does so very well. Time & Date is simply another API the OS provides, IMO.

Of course, that's a rant I should save for Sun... ;-)

> However, I don't know whether such a change would fix the problem I
> reported anyway. The problem I have is that the JVM is sometimes unable
> to determine which time-zone it is in.
I think it will solve it, because finding out in which time-zone should be done by calling one of the shared libraries the OS provides that does this (I'm assuming there is such a lib...) rather than duplicate the code, which undoubtedly has already been written by someone.

Anyway - it's just an opinion and as I said, I agree this should be directed to Sun and not Ubuntu.
Cheers.

Javier Barroso (javibarroso) wrote :

Please fix this bug. We are deploying ubuntu in our environment, and have many java developpers.

All have to create a symlink to /usr/share/zoneinfo/Europe/Madrid

Thank you

Soks (soks86) wrote :

I'm on the latest version of Ubuntu 9.10 with Java 1.6.0_15-b03 and I ran into the exact same problem. Had to create a symlink for /etc/localtime.

According to sun this is fixed in 1.6.0_18-b02. Would it be possible to get the repository updated with the newest version (I looked around and couldn't find a way to help out with this) so that this bug could be closed already.

Thank you.

Mark Renouf (mark-renouf) wrote :

Looks like this was fixed in Java 6u18!

http://java.sun.com/javase/6/webnotes/6u18.html
 ==> 6456628 java classes_util_i18n (tz) Default timezone is incorrectly set occasionally on Linux

(Sun Bug #6456628 is now listed as "Fix Shipped")

Java 6u20 is available for Ubuntu 10.04 as of today!

Upgradeable: sun-java6-jdk
    6-16-0ubuntu1.9.04 (-58.0MB)
    6.20dlj-1ubuntu2 (+62.5MB)

sun-java6-plugin_6.20dlj-1ubuntu2_i386.deb
sun-java6-javadb_6.20dlj-1ubuntu2_all.deb
sun-java6-jdk_6.20dlj-1ubuntu2_i386.deb
sun-java6-bin_6.20dlj-1ubuntu2_i386.deb
sun-java6-jre_6.20dlj-1ubuntu2_all.deb
sun-java6-source_6.20dlj-1ubuntu2_all.deb

# java -version
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)

# apt-get update
# sudo apt-get install sun-java6-bin sun-java6-javadb sun-java6-jdk sun-java6-jre sun-java6-plugin sun-java6-source
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  sun-java6-demo openjdk-6-doc sun-java6-fonts
The following packages will be upgraded:
  sun-java6-bin sun-java6-javadb sun-java6-jdk sun-java6-jre sun-java6-plugin sun-java6-source
6 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Need to get 84.7MB of archives.
After this operation, 6,291kB of additional disk space will be used.

....

# java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)

### To test: ###

# ls -l /etc/localtime
-rw-r--r-- 1 root root 3519 2010-04-11 16:40 /etc/localtime

(I've also still got the /usr/share/zoneinfo/localtime => /etc/localtime symlink in place, as well as 'posixrules', which is a copy of my selected zoneinfo, "US/Eastern" a.k.a. "America/New_York")

# vi ShowDate.java
====SNIP=====
import java.util.Date;

public class ShowDate {
  public static void main(String[] arg) {
    System.out.println(new Date());
  }
}
====SNIP=====

# javac ShowDate.java
# java ShowDate
# date -u
Thu Apr 22 16:30:32 UTC 2010
# date
Thu Apr 22 12:30:34 EDT 2010
# java ShowDate
Thu Apr 22 12:30:44 EDT 2010

# date -s 20100301
Mon Mar 1 00:00:00 EST 2010

# java ShowDate
Mon Mar 01 00:00:05 EST 2010

# date -s 20100315
Mon Mar 15 00:00:00 EDT 2010

# java ShowDate
Mon Mar 15 00:00:02 EDT 2010

# sudo date -s 20100101
Fri Jan 1 00:00:00 EST 2010

# java ShowDate
Fri Jan 01 00:00:01 EST 2010

Can anyone else confirm the issue is resolved?

Mark Renouf (mark-renouf) wrote :

Re: "Java 6u20 is available for Ubuntu 10.04 as of today!"

Just a note, I forgot that I had enabled the Canonical Partner repo on this system. That is where this version of sun-java6-* is available from. So to get it, you'll need to add this to your apt sources:

deb http://archive.canonical.com/ lucid partner/main partner/restricted

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.