JDK-6941137 : DST broken when jre/lib/zi is moved elsewhere and replaced with symlink.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 6u18
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2010-04-06
  • Updated: 2011-03-07
  • Resolved: 2011-03-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6 JDK 7
1.4.2_29Fixed 6u23Fixed 7 b112Fixed
Description
FULL PRODUCT VERSION :
$ ./jdk1.6.0_18/bin/java -version
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux vm23.example.com 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 16:20:31 UTC 2009 i686 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
We maintain a central master copy of the Olsen ZI database, to which all our installed JVMs refer. So when a new JVM is installed, its lib/zi directory is replaced with a symlink to the master ZI database. This has worked fine for every Sun JVM except 1.6.0_18, which fails if the target of the lib/zi symlink is anywhere except in the lib directory itself. See below for details of how to reproduce.

  Interestingly, the reproduction below includes slf4j (http://www.slf4j.org) and logback (http://logback.qos.ch), but I can see the same problem with other logging frameworks. Perhaps there is some nontrivial bit of date processing typically done by logging frameworks which triggers this. I was not able to isolate the issue further.


I propose the following patch to sun.util.calendar.ZoneInfoFile, which fixes 
the issue.

--- ZoneInfoFile.java.orig	2010-04-13 17:00:24.098498207 +0100
+++ ZoneInfoFile.java	2010-04-13 19:32:10.000000000 +0100
@@ -457,13 +457,13 @@
     private static final String ziDir;
     static {
         ziDir = (String) AccessController.doPrivileged(new 
PrivilegedAction() {
 		    public Object run() {
 			String zi = System.getProperty("java.home") +
-			    File.separator + "lib" + File.separator + "zi";
+			    File.separator + "lib" + File.separator + "zi" + File.separator + 
"ZoneInfoMappings";
 			try {
-			    zi = new File(zi).getCanonicalPath();
+			    zi = new File(zi).getCanonicalFile().getParent();
 			} catch(Exception e) {
 			}
 		    return zi;
 	    	    } });
     }

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
$ uname -a
Linux vm23.example.com 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 16:20:31 UTC 2009 i686 GNU/Linux
$ pwd
/var/tmp/j6u18
$ ls
jdk-6u18-linux-i586.bin  logback-0.9.19.tar.gz  slf4j-1.5.11.tar.gz
$ bash ./jdk-6u18-linux-i586.bin
:
Done.
$ gunzip -c slf4j-1.5.11.tar.gz | tar xf -
$ gunzip -c logback-0.9.19.tar.gz | tar xf -
$ ls
jdk1.6.0_18  jdk-6u18-linux-i586.bin  logback-0.9.19  logback-0.9.19.tar.gz  slf4j-1.5.11  slf4j-1.5.11.tar.gz
$ export CLASSPATH=/var/tmp/j6u18/logback-0.9.19/logback-classic-0.9.19.jar:/var/tmp/j6u18/logback-0.9.19/logback-core-0.9.19.jar:/var/tmp/j6u18/slf4j-1.5.11/slf4j-api-1.5.11.jar:.
$ cat > Main.java <<EOF
> import java.util.Date;
> import java.util.Calendar;
> import java.text.SimpleDateFormat;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
> public class Main {
>     public static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
>     public static void main(String[] args) {
>         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss MMM dd yyyy Z zzzz");
>         sdf.setCalendar(Calendar.getInstance());
>         LOGGER.info("Local: " + sdf.format(new Date()));
>     }
> }
> EOF
$ jdk1.6.0_18/bin/javac Main.java
$ date --utc
Tue Mar 30 15:14:06 UTC 2010
$ TZ=US/Eastern jdk1.6.0_18/bin/java Main
11:14:49.443 [main] INFO  Main - Local: 11:14:49 Mar 30 2010 -0400 Eastern Daylight Time
$ cd jdk1.6.0_18/jre/lib/
$ rm -rf /var/tmp/zi
$ mv zi /var/tmp/
$ ln -s /var/tmp/zi zi
$ cd ../../../
$ TZ=US/Eastern jdk1.6.0_18/bin/java Main
10:15:42.527 [main] INFO  Main - Local: 10:15:42 Mar 30 2010 -0500 GMT-05:00
$ 


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was expecting the second run to yield a time zone of "-0400 Eastern Daylight Time".
ACTUAL -
A timezone of "-0500 GMT-05:00", which is incorrect now that the US is in DST.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
See "Steps to Reproduce"
---------- END SOURCE ----------

Release Regression From : 6u17
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION Fixed with NIO2 API for JDK7.
2010-09-10

EVALUATION It's a java.io problem, but we will use a workaround fix in the time zone code.
2010-08-16

WORK AROUND Disabling the canonicalization cache removes the problem: -Dsun.io.useCanonCaches=false -Dsun.io.useCanonPrefixCache=false However, it will affect runtime performance.
2010-04-07

EVALUATION sun.util.calendar.ZoneInfoFile was changed to call File.getCanonicalPath for fixing 6824265. There seems to be a canonicalization problem with its cache when the logging libraries are used. Transferring this CR to classes_io.
2010-04-07