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

Regression: java.util.ResourceBundle corrupts the value set with setParent()

XMLWordPrintable

    • beta2
    • generic, x86
    • generic, windows_nt



      Name: boT120536 Date: 12/07/2000


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


      Create a subclass of java.util.ListResourceBundle (It looks like the problem
      will occur for any sub-class of ResourceBundle)

      In the constructor of the sub-class call setParent() to set the parent of the
      resource bundle. The docs say that this method will set a resource bundle that
      will be searched if the key is not found in the current resource bundle.

      After java.util.ResourceBundle.getBundle() creates the bundle it calls
      setParent() on the subclass again - overwriting the value that was set. This
      didn't happen in 1.2

      The following code illustrates this, and why I want to do it

      // GeneralMessages.java
      /**
       * Messages the whole app needs
       */
      public class GeneralMessages extends java.util.ListResourceBundle {
      private static final Object[][] contents = {
      {"INSUFFICIENT_DATA_ERROR", "Insufficient data has been entered"},
      {"INPUT_ERROR", "Input Error"},
      };

      public GeneralMessages() {
      super();
      }
      protected java.lang.Object[][] getContents() {
      return contents;
      }
      }

      // Screen1Messages.java


      // TestResourceBundleCorruption.java
      /**
       * Messages screen 1 needs
       */
      public class Screen1Messages extends java.util.ListResourceBundle {
      private static final Object[][] contents = {
      {"INV_DATE", "Enter a valid date in DD/MMM/YYYY format."},
      {"INV_START_DATE_PAST", "The date cannot be before Jan 01, 1901."},
      };
      public Screen1Messages() {
      setParent(getBundle("GeneralMessages"));
      }
      protected java.lang.Object[][] getContents() {
      return contents;
      }
      }

      import java.util.*;
      /**
       * Test the external modification of the resource bundle parenting
       */
      public class TestResourceBundleCorruption {
      public static void main(java.lang.String[] args) {
      ResourceBundle screen1Messages = ResourceBundle.getBundle
      ("Screen1Messages");

      System.out.println("Invalid date message (in Screen1Messages): " +
      screen1Messages.getString("INV_DATE"));
      System.out.println("Input error message (in parent): " +
      screen1Messages.getString("INPUT_ERROR"));
      }
      }

      ------------------------

      I looked at the findBundle() method of java.util.ResourceBundle
      and from what I can tell it's trying to setup the parent tree so
      A is the parent of A_en is the parent of A_en_CA. In fact it looks like
      someone went to a lot of trouble to do this, the code is much trickier than
      it was in 1.2.

      This breaks my code, and I'm not sure I think it's a good idea anyway. The
      language tree I set up by naming my files is completely unrelated to the search
      tree I want when looking for messages. If I don't find my message in french, I
      don't want an English one. And if I did, I would just call setParent() as
      above.

      If this really was a design change, which is what it looks like, then
      setParent() should be removed, or made private, or deprecated at the least.
      (Review ID: 113074)
      ======================================================================

      Name: rmT116609 Date: 01/10/2001


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

      In our project, we used a framework, described below, to deal with
      ResourceBundle. This framework worked well with JDK1.2. We now upgrade to
      JDK1.3, and the application throws MissingResourceException. It's strange that
      the problem only happen when we run by 1.3 runtime, doesn't matter if we
      compiled with JDK1.2 or 1.3. If we compile with JDK1.3 and run with 1.2
      runtime, the application still work well.

      The frame work is as follows:
      - Assume we have class (as an application with main method) A with a
      ListResourceBundle called AResources.
      - We then have class B that extends A, and its resource class is BResources,
      that extends AResources. In the constructor of BResources, we use getBundle to
      load AResources and set this bundle as BResources's parent (using setParent)
      - When we use setBundle to load BResources, a check on BResources's parent
      returns null, results to inability to locate resources in AResources.

      Here are classes listing:
      A.java -------
      import java.util.*;

      class A {
      public ResourceBundle resources;

      public A() {
      resources = ResourceBundle.getBundle("AResources");
      }

          public static void main(String[] args) {
              //ResourceBundle bundle = ResourceBundle.getBundle("MyListResources");
      A myApp = new A();
              System.out.println(myApp.resources.getString("key-1")); // wombat
              System.out.println(myApp.resources.getStringArray("key-2")[0]); // apple
              System.out.println(myApp.resources.getObject("key-3"));
                                                      // java.awt.Point[x=1,y=2]
          }
      }

      AResources.java ------------------
      import java.awt.*;
      import java.util.*;

      public class AResources extends ListResourceBundle {
          public Object[][] getContents() {
              return contents;
          }

          private Object[][] contents = {
              {"key-1", "wombat",},
              {"key-2", new String[]{"apple", "blueberry", "cantaloupe",}},
              {"key-3", new Point(1, 2),},
          };

      public ResourceBundle getParent() {
      return parent;
      }
      }

      BResources.java -------------
      import java.util.*;

      public class BResources extends AResources {

      public BResources () {
      ResourceBundle resources = ResourceBundle.getBundle("AResources");
      setParent(resources);
      System.out.println(resources);
      }

          public Object[][] getContents() {
              return contents;
          }

          private Object[][] contents = {
              {"key-4", "value-4"},
              {"key-5", "value-5"},
              {"key-6", "value-6"}
          };

      }

      B.java---------------
      import java.util.*;

      class B extends A {

      public B() {
      resources = ResourceBundle.getBundle("BResources");
      }

          public static void main(String[] args) {
              //ResourceBundle bundle = ResourceBundle.getBundle("MyListResources");
      B myApp = new B();
      System.out.println(myApp.resources);
      System.out.println(((BResources)myApp.resources).getParent());
              System.out.println(myApp.resources.getString("key-4")); // wombat
              System.out.println(myApp.resources.getString("key-1")); // wombat
              System.out.println(myApp.resources.getStringArray("key-2")[0]); // apple
              System.out.println(myApp.resources.getObject("key-3"));
                                                      // java.awt.Point[x=1,y=2]
          }
      }

      Run "java B" by JRE1.2 gives:------------------
      AResources@6d2ec615
      BResources@6a8ac615
      AResources@6d2ec615
      value-4
      wombat
      apple
      java.awt.Point[x=1,y=2]

      Run "java B" by JRE1.3 gives:------------------
      AResources@129206
      BResources@55af5
      null
      value-4
      Exception in thread "main" java.util.MissingResourceException: Can't find
      resource for bundle BResources, key key-1
              at java.util.ResourceBundle.getObject(ResourceBundle.java:382)
              at java.util.ResourceBundle.getString(ResourceBundle.java:354)
              at B.main(B.java:15)

      Please check this bug, as it forces us stick with JDK1.2 and prevents us from
      taking advantages of JDK1.3
      (Review ID: 114370)
      ======================================================================

            nlindenbsunw Norbert Lindenberg (Inactive)
            bonealsunw Bret O'neal (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: