8013086: NPE thrown by SimpleDateFormat with TimeZoneNameProvider supplied
authornaoto
Tue, 07 May 2013 11:31:08 -0700
changeset 17440 fb37aa6b305e
parent 17439 2205a12f3414
child 17441 5ae43433d158
8013086: NPE thrown by SimpleDateFormat with TimeZoneNameProvider supplied Reviewed-by: okutsu
jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java
jdk/test/java/util/Locale/LocaleProviders.java
jdk/test/java/util/Locale/LocaleProviders.sh
--- a/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java	Tue May 07 20:00:47 2013 +0200
+++ b/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java	Tue May 07 11:31:08 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -239,14 +239,25 @@
 
             for (int i = 1; i <= 4; i ++) {
                 names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
-                if (i >= 3 && names[i] == null) {
-                    names[i] = names[i-2];
+
+                if (names[i] == null) {
+                    switch (i) {
+                    case 1:
+                        // this id seems not localized by this provider
+                        return null;
+                    case 2:
+                    case 4:
+                        // If the display name for SHORT is not supplied,
+                        // copy the LONG name.
+                        names[i] = names[i-1];
+                        break;
+                    case 3:
+                        // If the display name for DST is not supplied,
+                        // copy the "standard" name.
+                        names[3] = names[1];
+                        break;
                 }
             }
-
-            if (names[1] == null) {
-                // this id seems not localized by this provider
-                names = null;
             }
 
             return names;
--- a/jdk/test/java/util/Locale/LocaleProviders.java	Tue May 07 20:00:47 2013 +0200
+++ b/jdk/test/java/util/Locale/LocaleProviders.java	Tue May 07 11:31:08 2013 -0700
@@ -60,6 +60,10 @@
                 bug8010666Test();
                 break;
 
+            case "bug8013086Test":
+                bug8013086Test(args[1], args[2]);
+                break;
+
             default:
                 throw new RuntimeException("Test method '"+methodName+"' not found.");
         }
@@ -142,4 +146,13 @@
             }
         }
     }
+
+    static void bug8013086Test(String lang, String ctry) {
+        try {
+            // Throws a NullPointerException if the test fails.
+            System.out.println(new SimpleDateFormat("z", new Locale(lang, ctry)).parse("UTC"));
+        } catch (ParseException pe) {
+            // ParseException is fine in this test, as it's not "UTC"
 }
+    }
+}
--- a/jdk/test/java/util/Locale/LocaleProviders.sh	Tue May 07 20:00:47 2013 +0200
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh	Tue May 07 11:31:08 2013 -0700
@@ -24,6 +24,7 @@
 #
 # @test
 # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8010666
+#      8013086 
 # @summary tests for "java.locale.providers" system property
 # @compile -XDignore.symbol.file LocaleProviders.java
 # @run shell/timeout=600 LocaleProviders.sh
@@ -69,7 +70,7 @@
     ;;
 esac
 
-# create an SPI implementation
+# create SPI implementations
 mk() {
   d=`dirname $1`
   if [ ! -d $d ]; then mkdir -p $d; fi
@@ -88,16 +89,38 @@
     }
 
     public Locale[] getAvailableLocales() {
-        Locale[] locales = {Locale.GERMAN, Locale.US, Locale.JAPANESE, Locale.CHINESE};
+        Locale[] locales = {Locale.US};
+        return locales;
+    }
+}
+EOF
+mk ${SPIDIR}${FS}src${FS}tznp8013086.java << EOF
+import java.util.spi.TimeZoneNameProvider;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class tznp8013086 extends TimeZoneNameProvider {
+    public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {
+        if (!daylight && style==TimeZone.LONG) {
+            return "tznp8013086";
+        } else {
+            return null;
+        }
+    }
+
+    public Locale[] getAvailableLocales() {
+        Locale[] locales = {Locale.JAPAN};
         return locales;
     }
 }
 EOF
 mk ${SPIDIR}${FS}dest${FS}META-INF${FS}services${FS}java.util.spi.TimeZoneNameProvider << EOF
 tznp
+tznp8013086
 EOF
 ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d ${SPIDIR}${FS}dest \
-    ${SPIDIR}${FS}src${FS}tznp.java
+    ${SPIDIR}${FS}src${FS}tznp.java \
+    ${SPIDIR}${FS}src${FS}tznp8013086.java
 ${COMPILEJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS} cvf ${SPIDIR}${FS}tznp.jar -C ${SPIDIR}${FS}dest .
 
 # get the platform default locales
@@ -269,4 +292,12 @@
   runTest
 fi
 
+# testing 8013086 fix.
+METHODNAME=bug8013086Test
+PREFLIST="JRE,SPI -Djava.ext.dirs=${SPIDIR}"
+PARAM1=ja
+PARAM2=JP
+PARAM3=
+runTest
+
 exit $result