Bug 995488

Summary: Java thinks that the default timezone is Busingen instead of Zurich
Product: Red Hat Enterprise Linux 6 Reporter: Julien Tognazzi <julien.tognazzi>
Component: java-1.6.0-openjdkAssignee: jiri vanek <jvanek>
Status: CLOSED CURRENTRELEASE QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 6.4CC: ahughes, julien.tognazzi, jvanek, lzachar, michele, nphilipp, omajid, pmachata
Target Milestone: rcKeywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-10-30 06:18:14 EDT Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Attachments:
Description Flags
TimeZone.java test program none

Description Julien Tognazzi 2013-08-09 10:09:12 EDT
Created attachment 784860 [details]
TimeZone.java test program

Description of problem:
OpenJDK doesn't determine the correct system timezone if it is set to Europe/Zurich.

Version-Release number of selected component (if applicable):
tzdata-java-2013c-2.el6.noarch
java-1.6.0-openjdk-1.6.0.0-1.62.1.11.11.90.el6_4.x86_64

How reproducible:


Steps to Reproduce:
1. Set your system timezone to Europe/Zurich
2. execute the java test program attached


Actual results:
sun.util.calendar.ZoneInfo[id="Europe/Busingen",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=Europe/Busingen,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]


Expected results:
sun.util.calendar.ZoneInfo[id="Europe/Zurich",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=Europe/Zurich,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]


Additional info:
It seems to me that java try to determine the system timezone from /etc/localtime.
It then searches its zoneinfo for a matching file.
But as the new Busigen timezone data is an exact copy of the Zurich one, the first matching zone is the Busigen one.

Busingen is a new addition to the tzdata for 2013. see 
https://rhn.redhat.com/errata/RHEA-2013-0674.html
Comment 2 Petr Machata 2013-08-11 17:24:55 EDT
Switching to Java team.  I don't think I can influence what Java does from inside tzdata, but please let me know if I can help you.
Comment 9 Omair Majid 2013-08-21 14:03:37 EDT
(In reply to Julien Tognazzi from comment #0)
> sun.util.calendar.ZoneInfo[id="Europe/Busingen",offset=3600000,
> dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.
> SimpleTimeZone[id=Europe/Busingen,offset=3600000,dstSavings=3600000,
> useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,
> startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,
> endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]

Please correct me if I am wrong, but there's no actual API that incorrectly returns "Europe/Busingen" instead of the "Europe/Zurich"? It's just the string representation of the TimeZone object that's wrong?

> Additional info:
> It seems to me that java try to determine the system timezone from
> /etc/localtime.
> It then searches its zoneinfo for a matching file.
> But as the new Busigen timezone data is an exact copy of the Zurich one, the
> first matching zone is the Busigen one.

This is exactly what happens in this case.
Comment 10 Julien Tognazzi 2013-08-22 03:37:55 EDT
(In reply to Omair Majid from comment #9)
> (In reply to Julien Tognazzi from comment #0)
> > sun.util.calendar.ZoneInfo[id="Europe/Busingen",offset=3600000,
> > dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.
> > SimpleTimeZone[id=Europe/Busingen,offset=3600000,dstSavings=3600000,
> > useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,
> > startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,
> > endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
> 
> Please correct me if I am wrong, but there's no actual API that incorrectly
> returns "Europe/Busingen" instead of the "Europe/Zurich"? It's just the
> string representation of the TimeZone object that's wrong?
> 
I'm not sure I understand your question...
But the thing is that the system is configured with "Europe/Zurich" and Java recognizes it as "Europe/Busingen".

I saw error connecting to a PostgreSQL with JDBC as the DB server didn't know about "Europe/Busingen".
Also some third party java program (from Atlassian) badly complained about it.
Comment 12 Omair Majid 2013-08-28 13:15:22 EDT
Unfortunately, I am not sure that there's anything we can do. The behaviour of OpenJDK is not ideal, but there is no well-known or canonical way to identify the default timezone name other than by guessing what /etc/localtime corresponds to. The default timezone is actually specified in /etc/sysconfig/clock, but parsing that file leads to lots of other issues (see bug 489586) and is explicitly unsupported.

Given that there is no systematic way of identifying the default timezone, I am afraid I have to close this as CANTFIX.
Comment 14 Andrew John Hughes 2013-08-28 20:27:34 EDT
As Omair detailed in [0], searching for the first applicable timezone is the last attempt OpenJDK makes, having failed to get the timezone from the environment variable, TZ, the file /etc/timezone and by reading the symlink /etc/localtime.  Thus, any of these is a possible workaround for this issue.

Adding /etc/timezone is probably the safest, assuming it doesn't already exist, as it's less likely to be altered by future package installs.

# echo "Europe/Zurich" > /etc/localtime

should solve your problem.

[0] http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-August/020229.html
Comment 15 Petr Machata 2013-08-28 21:21:34 EDT
(In reply to Andrew John Hughes from comment #14)
> /etc/localtime.  Thus, any of these is a possible workaround for this issue.

I don't think converting /etc/localtime to symlink is an option.  The tzdata trigger would overwrite that back to full file next time tzdata is updated.  We'd have to update the tzdata trigger (which resides in the glibc package) to symlink the zone instead of copying it.

That would break early logging on installations that have separately-mounted /usr (the stamps would be off).  I don't know how numerous those are.  It's a pretty ancient consideration, and UsrMove in RHEL 7 breaks that use case anyway, as far as I understand.

> Adding /etc/timezone is probably the safest, assuming it doesn't already
> exist, as it's less likely to be altered by future package installs.

It's also less likely to be updated by system-config-date, I reckon?
 
> # echo "Europe/Zurich" > /etc/localtime

Here you mean > /etc/timezone, right?

Again (and publicly this time), why not rely on /etc/sysconfig/clock stability?  We rely on it anyway...
Comment 16 Julien Tognazzi 2013-08-29 08:23:24 EDT
Ok thank you for these explanations.

But could it be possible that Anaconda/system-config-date set the correct value in /etc/timezone then?
If not for rhel6 maybe for rhel7 or next fedora...
Comment 17 Omair Majid 2013-08-29 10:19:17 EDT
(In reply to Julien Tognazzi from comment #16)
> But could it be possible that Anaconda/system-config-date set the correct
> value in /etc/timezone then?

It does. Except it doesn't provide any (non-hacky) way for any other application to guess what file /etc/timezone corresponds to. This is why Java does a file compare and guesses the time zone (incorrectly).

> If not for rhel6 maybe for rhel7 or next fedora...

For Fedora (at least 19), there is no /etc/sysconfig/clock file and /etc/localtime is a symlink. OpenJDK handles this case correctly (as far as I can see). This bug should not happen there at all.

Since RHEL 7 will be based on Fedora 19 (or something along those lines), I would guess that it should be okay too.
Comment 18 Julien Tognazzi 2013-08-29 10:32:23 EDT
Here I really meant /etc/timezone ;-) not /etc/localtime...

I was referring to the comment #14 where one of the workaround would be to populate the file /etc/timezone with "Europe/Zurich".

So why couldn't the diverse system tools (anaconda, etc) set this file with the corresponding timezone string ? 
Java would be happy then.
Comment 19 Andrew John Hughes 2013-08-29 12:17:44 EDT
(In reply to Petr Machata from comment #15)
> (In reply to Andrew John Hughes from comment #14)
> > /etc/localtime.  Thus, any of these is a possible workaround for this issue.
> 
> I don't think converting /etc/localtime to symlink is an option.  The tzdata
> trigger would overwrite that back to full file next time tzdata is updated. 
> We'd have to update the tzdata trigger (which resides in the glibc package)
> to symlink the zone instead of copying it.
> 
> That would break early logging on installations that have separately-mounted
> /usr (the stamps would be off).  I don't know how numerous those are.  It's
> a pretty ancient consideration, and UsrMove in RHEL 7 breaks that use case
> anyway, as far as I understand.

Yes, that's exactly why I said /etc/timezone is safest below.  A separate /usr is broken by all manner of things and systemd finally puts it out to pasture in RHEL 7, I believe.  For example, a separate /usr is tied to a root partition that provides certain versions of various libraries by virtue of dynamic linking against those stored in /lib or /lib64.

> 
> > Adding /etc/timezone is probably the safest, assuming it doesn't already
> > exist, as it's less likely to be altered by future package installs.
> 
> It's also less likely to be updated by system-config-date, I reckon?
>  
> > # echo "Europe/Zurich" > /etc/localtime
> 
> Here you mean > /etc/timezone, right?
> 

Yes, sorry.  Typo.

As far as I can see, this file is available on Gentoo, Debian & Ubuntu but not on RHEL/Fedora at present.  So it provides a fairly perfect solution of a file that existing RHEL tools won't touch but which OpenJDK is already aware of, due to its presence on other distros.

> Again (and publicly this time), why not rely on /etc/sysconfig/clock
> stability?  We rely on it anyway...

Do we?  We had support in OpenJDK removed four years ago because it was causing issues (the timezone specification in that file doesn't always match the Olson format; see the bug Omair referred to).  I don't see a strong reason to reintroduce it when there's an alternative workaround, especially as there's no evidence that the original problem has been fixed in another way.
Comment 20 Petr Machata 2013-08-30 06:53:36 EDT
(In reply to Andrew John Hughes from comment #19)
> > Again (and publicly this time), why not rely on /etc/sysconfig/clock
> > stability?  We rely on it anyway...
> 
> Do we?  We had support in OpenJDK removed four years ago because it was
> causing issues (the timezone specification in that file doesn't always match
> the Olson format; see the bug Omair referred to).  

Yes we do.  I read that BZ, and it's not clear whether the bug was fixed, but I sure hope it was.  If there's anything else than Olson ID in /etc/sysconfig/clock, /etc/localtime doesn't get updated when tzdata is.  So we do depend on semantics and format of that file at least in RHEL 6, 5 and 4, and possibly 3 as well, though I didn't look.

> I don't see a strong
> reason to reintroduce it when there's an alternative workaround, especially
> as there's no evidence that the original problem has been fixed in another
> way.

Using /etc/timezone is a workaround only as far as system-config-date knows to update it.  Does it?
Comment 21 Andrew John Hughes 2013-09-02 07:53:54 EDT
(In reply to Petr Machata from comment #20)
> (In reply to Andrew John Hughes from comment #19)
> > > Again (and publicly this time), why not rely on /etc/sysconfig/clock
> > > stability?  We rely on it anyway...
> > 
> > Do we?  We had support in OpenJDK removed four years ago because it was
> > causing issues (the timezone specification in that file doesn't always match
> > the Olson format; see the bug Omair referred to).  
> 
> Yes we do.  I read that BZ, and it's not clear whether the bug was fixed,
> but I sure hope it was.  If there's anything else than Olson ID in
> /etc/sysconfig/clock, /etc/localtime doesn't get updated when tzdata is.  So
> we do depend on semantics and format of that file at least in RHEL 6, 5 and
> 4, and possibly 3 as well, though I didn't look.
> 

OpenJDK is only available on RHEL 5 & 6.  Is /etc/sysconfig/clock continually updated?  I get the impression from that bug that it isn't, so if it was wrong at some point, older systems will still have a broken version.

> > I don't see a strong
> > reason to reintroduce it when there's an alternative workaround, especially
> > as there's no evidence that the original problem has been fixed in another
> > way.
> 
> Using /etc/timezone is a workaround only as far as system-config-date knows
> to update it.  Does it?

It would be easier to add support for /etc/timezone there than rollback the OpenJDK change and risk breaking systems.
Comment 22 Petr Machata 2013-09-02 09:42:09 EDT
(In reply to Andrew John Hughes from comment #21)
> Is /etc/sysconfig/clock continually updated?  I get the impression from that 
> bug that it isn't, so if it was wrong at some point, older systems will still 
> have a broken version.

Only s-c-d updates it far as I know.  Honestly I would welcome if Nils commented here.  If it's likely that we shipped s-c-d that produced "wrong" /etc/sysconfig/clock in RHEL, then that's something that we need to fix somewhere.

> > Using /etc/timezone is a workaround only as far as system-config-date knows
> > to update it.  Does it?
> 
> It would be easier to add support for /etc/timezone there than rollback the
> OpenJDK change and risk breaking systems.

That would work as well.  We could then sanction /etc/timezone as the API between s-c-d and the rest of the system, tzdata-update would be patched to prefer that file if it's available, and /etc/sysconfig/clock could formally become the dumping ground that it claims to be.
Comment 23 Nils Philippsen 2013-09-02 09:53:42 EDT
Petr, you snuck your comment in right before mine, thanks for the mid-air collision ;-).

Here's my take on it:

- As far as I know, only s-c-date (or anaconda using its code) writes /etc/sysconfig/clock.
- There are no guarantees that /etc/sysconfig/clock is updated if /etc/localtime is changed outside of s-c-date.
- As I understand it, ZONE in /etc/sysconfig/clock can deviate from the Olson format in that it may contain spaces instead of underscores. This is probably an inherited issue, apparently the code writing the file was written more with the UI in mind than tzdata. However, that's pure speculation, it comes from before I worked on s-c-date. If there's anything else that's wrong in that file, I'd like to know it.
- That this file is used by glibc or whatever triggers to update /etc/localtime is news to me, yet in hindsight it's probably the only reliable way to do so. Still, a heads up would have been nice given my comments in bug 489586.

Feel free to use the information in the file, with the above caveats in mind, I don't plan any changes in the file format for the remainder of RHEL <= 6 anyhow. The comments in the file will stay however, to scare off potential unsuspecting users who don't know these details from using it naïvely. I fear that they'll do so anyhow, but what can you do... :-/

I guess I could add support for /etc/timezone to s-c-date but right now it doesn't know about it.
Comment 24 Petr Machata 2013-09-02 17:26:12 EDT
(In reply to Nils Philippsen from comment #23)
> Petr, you snuck your comment in right before mine, thanks for the mid-air
> collision ;-).

Couldn't resist!

> - As I understand it, ZONE in /etc/sysconfig/clock can deviate from the
> Olson format in that it may contain spaces instead of underscores.

Bug 489586 is from 2009, RHEL 6 was released at the end of 2010, and indeed RHEL 6 s-c-d contains this line in timezoneBackend.py:

>        timezonefile = timezone.replace (' ', '_')

(It then goes on to write this to /etc/sysconfig/clock.  There's a bunch of lines like this, apparently converting spaces to underscores and vice versa is something that s-c-d does a lot.)
So we are covered at least in RHEL 6.

> a heads up would have been nice given my comments in bug 489586.

Sorry, I had no idea this bug existed.  And back then I may not have known full context myself anyway.

> I guess I could add support for /etc/timezone to s-c-date but right now it
> doesn't know about it.

This doesn't seem to be necessary.  If java cares about this data, it can get it from /etc/sysconfig/clock reliably in RHEL 6.  In RHEL 7 it's moot.
Comment 25 Petr Machata 2013-09-02 17:27:56 EDT
Looking into s-c-d in RHEL 5, that doesn't do any fishy underscore business at all, so we are safe back there as well.  Nice.
Comment 26 Omair Majid 2013-09-03 15:15:21 EDT
Okay, if /etc/sysconfig/clock is a reliable source of timezone name, then it should be possible to fix this. Reopening.
Comment 27 Nils Philippsen 2013-09-04 07:01:16 EDT
(In reply to Petr Machata from comment #24)
> (In reply to Nils Philippsen from comment #23)
> > a heads up would have been nice given my comments in bug 489586.
> 
> Sorry, I had no idea this bug existed.  And back then I may not have known
> full context myself anyway.

No worries :).
Comment 28 jiri vanek 2013-09-05 04:01:17 EDT
I will include this bug fix in  release I'm currently working in. As pm ack is on +, and exists both testcase and fix, I would guess qa and devel acks will be metter of hours.
Comment 29 Andrew John Hughes 2013-09-05 09:04:54 EDT
No, there is no reason to add this support back, especially when it may break existing setups in a far worse way than merely picking up the wrong timezone name.

Please just support /etc/timezone which is already used on other distros and searched for by both OpenJDK and the proprietary JDK and will thus fix this bug on the proprietary JDKs as well.
Comment 30 Andrew John Hughes 2013-09-05 09:36:59 EDT
I don't see this with Europe/Zurich.  I do with Europe/Busingen and Europe/London on both OpenJDK 6 & 7.

# cat /etc/sysconfig/clock 
# The time zone of the system is defined by the contents of /etc/localtime.
# This file is only for evaluation by system-config-date, do not rely on its
# contents elsewhere.
ZONE="Europe/Busingen"
# /usr/lib/jvm/java-1.6.0-openjdk.x86_64/bin/java TimeZoneTest
sun.util.calendar.ZoneInfo[id="Europe/Zurich",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=Europe/Zurich,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
# /usr/lib/jvm/java-1.7.0-openjdk.x86_64/bin/java TimeZoneTest
sun.util.calendar.ZoneInfo[id="Europe/Zurich",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=Europe/Zurich,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]

# cat /etc/sysconfig/clock 
# The time zone of the system is defined by the contents of /etc/localtime.
# This file is only for evaluation by system-config-date, do not rely on its
# contents elsewhere.
ZONE="Europe/London"
# /usr/lib/jvm/java-1.6.0-openjdk.x86_64/bin/java TimeZoneTest
sun.util.calendar.ZoneInfo[id="GB-Eire",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=GB-Eire,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
# /usr/lib/jvm/java-1.7.0-openjdk.x86_64/bin/java TimeZoneTest
sun.util.calendar.ZoneInfo[id="GB-Eire",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=GB-Eire,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]

GCJ, however:

# /usr/lib/jvm/java-1.5.0-gcj/bin/java TimeZoneTest
gnu.java.util.ZoneInfo[id=Europe/London,offset=0,transitions=243,useDaylight=true,dstSavings=3600000,lastRule=java.util.SimpleTimeZone[id=GMT0BST,M3.5.0/1,M10.5.0,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=0,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]

;-)
Comment 31 Omair Majid 2013-09-05 10:55:03 EDT
(In reply to Andrew John Hughes from comment #29)
> Please just support /etc/timezone which is already used on other distros and
> searched for by both OpenJDK and the proprietary JDK and will thus fix this
> bug on the proprietary JDKs as well.

This is a good point. If /etc/timezone is added, proprietary JDKs as well as built-from-upstream OpenJDK will work better too.
Comment 32 Petr Machata 2013-09-06 10:23:52 EDT
(In reply to Omair Majid from comment #31)
> (In reply to Andrew John Hughes from comment #29)
> > Please just support /etc/timezone which is already used on other distros and
> > searched for by both OpenJDK and the proprietary JDK
> 
> This is a good point.

I agree, it is.
Comment 33 Andrew John Hughes 2013-09-23 19:42:29 EDT
Workaround now in 7:

* http://blog.fuseyism.com/index.php/2013/09/07/icedtea-1-11-13-released/
* http://blog.fuseyism.com/index.php/2013/09/23/icedtea-2-4-2-released/

Active only on distros with /etc/sysconfig/clock that aren't Fedora.
Comment 34 jiri vanek 2013-10-30 06:18:14 EDT
after next release (in week time) this will be available in all rhels x openjdks