jdk/test/java/util/ResourceBundle/Bug4168625Test.java
changeset 7008 0bac31837ad2
parent 5801 8008ed6e4a37
child 7253 58ff073169cb
equal deleted inserted replaced
7007:36b01e053bd7 7008:0bac31837ad2
    23 /*
    23 /*
    24     @test
    24     @test
    25     @summary test Resource Bundle for bug 4168625
    25     @summary test Resource Bundle for bug 4168625
    26     @build Bug4168625Class Bug4168625Getter Bug4168625Resource Bug4168625Resource3 Bug4168625Resource3_en Bug4168625Resource3_en_CA Bug4168625Resource3_en_IE Bug4168625Resource3_en_US Bug4168625Resource2_en_US Bug4168625Resource2
    26     @build Bug4168625Class Bug4168625Getter Bug4168625Resource Bug4168625Resource3 Bug4168625Resource3_en Bug4168625Resource3_en_CA Bug4168625Resource3_en_IE Bug4168625Resource3_en_US Bug4168625Resource2_en_US Bug4168625Resource2
    27     @run main/timeout=600 Bug4168625Test
    27     @run main/timeout=600 Bug4168625Test
    28     @bug 4168625
    28     @bug 4168625 6993339
    29 */
    29 */
    30 /*
    30 /*
    31  *
    31  *
    32  *
    32  *
    33  * (C) Copyright IBM Corp. 1999 - All Rights Reserved
    33  * (C) Copyright IBM Corp. 1999 - All Rights Reserved
    48 
    48 
    49 import java.util.*;
    49 import java.util.*;
    50 import java.io.*;
    50 import java.io.*;
    51 
    51 
    52 /**
    52 /**
    53  *  This test tries to correct three efficiency problems with the caching
    53  *  This test tries to correct two efficiency problems with the caching
    54  *  mechanism of ResourceBundle.  All tests assume that none of the bundles
    54  *  mechanism of ResourceBundle.  It also allows concurrent loads
    55  *  have been previously loaded and cached.  It also allows concurrent loads
       
    56  *  of resource bundles to be performed if the bundles are unrelated (ex. a
    55  *  of resource bundles to be performed if the bundles are unrelated (ex. a
    57  *  load of a local system resource by one thread while another thread is
    56  *  load of a local system resource by one thread while another thread is
    58  *  doing a slow load over a network).
    57  *  doing a slow load over a network).
    59  */
    58  */
    60 public class Bug4168625Test extends RBTestFmwk {
    59 public class Bug4168625Test extends RBTestFmwk {
   228         if (dups) {
   227         if (dups) {
   229             errln("Resource bundle not caching some classes properly");
   228             errln("Resource bundle not caching some classes properly");
   230         }
   229         }
   231     }
   230     }
   232 
   231 
   233     /**
       
   234      *  Previous versions of ResourceBundle exhibited the following caching behavior.
       
   235      *  Assume the class Bug4168625Resource_en exists. Bug4168625Resource_en_US does
       
   236      *  not.  Two threads, ThreadA and ThreadB both try to get the same bundle.
       
   237      *  <P>
       
   238      *  <pre>
       
   239      *  ThreadA.getBundle("Bug4168625Resource", new Locale("en", "US"));
       
   240      *      A-->try to load Bug4168625Resource_en_US
       
   241      *  ThreadB.getBundle("Bug4168625Resource", new Locale("en", "US"));
       
   242      *      B-->try to load Bug4168625Resource_en_US
       
   243      *      B-->load Bug4168625Resource_en (#1)
       
   244      *      A-->load Bug4168625Resource_en (#2)
       
   245      *      A-->cache Bug4168625Resource_en (#2) as Bug4168625Resource_en
       
   246      *      A-->cache Bug4168625Resource_en (#2) as Bug4168625Resource_en_US
       
   247      *      A-->return Bug4168625Resource_en (#2)
       
   248      *      B-->cache Bug4168625Resource_en (#1) as Bug4168625Resource_en
       
   249      *      B-->cache Bug4168625Resource_en (#1) as Bug4168625Resource_en_US
       
   250      *      B-->return Bug4168625Resource_en (#1)
       
   251      *  </pre>
       
   252      *  <P>
       
   253      *  Both threads try and fail to load Bug4168625Resource_en_US.  Both
       
   254      *  threads load Bug4168625Resource_en.  Both threads get their own copy
       
   255      *  of the Bug4168625Resource_en resource.
       
   256      *
       
   257      *  The desired behavior is as follows:
       
   258      *  <P>
       
   259      *  <pre>
       
   260      *  ThreadA.getBundle("Bug4168625Resource", new Locale("en", "US"));
       
   261      *      A-->try to load Bug4168625Resource_en_US
       
   262      *  ThreadB.getBundle("Bug4168625Resource", new Locale("en", "US"));
       
   263      *      B-->try to load Bug4168625Resource_en_US
       
   264      *      B-->load Bug4168625Resource_en
       
   265      *      A-->load Bug4168625Resource_en (block in ResourceBundle.getBundle)
       
   266      *      B-->cache Bug4168625Resource_en as Bug4168625Resource_en
       
   267      *      B-->cache Bug4168625Resource_en as Bug4168625Resource_en_US
       
   268      *      A-->return Bug4168625Resource_en
       
   269      *      B-->return Bug4168625Resource_en
       
   270      *  </pre>
       
   271      *  <P>
       
   272      *  Note that both threads return the same bundle object.
       
   273      */
       
   274     public void testConcurrentLoading1() throws Exception {
       
   275         final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
       
   276         final Class c = loader.loadClass("Bug4168625Class");
       
   277         final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();
       
   278 
       
   279             //both threads want the same resource
       
   280         ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "US"));
       
   281         ConcurrentLoadingThread thread2 = new ConcurrentLoadingThread(loader, test, new Locale("en", "US"));
       
   282 
       
   283         thread1.start();            //start thread 1
       
   284         loader.waitForNotify(1);    //wait for thread1 to do getBundle & block in loader
       
   285         thread2.start();            //start second thread
       
   286         loader.waitForNotify(2, 1000);  //wait until thread2 blocks somewhere in getBundle
       
   287         thread1.ping();             //continue both threads
       
   288         thread2.ping();
       
   289 
       
   290         thread1.join();             //wait unitl both threads complete
       
   291         thread2.join();
       
   292 
       
   293             //Now, examine the class loads that were done.
       
   294         loader.logClasses("Classes loaded after completion of both threads:");
       
   295 
       
   296         boolean dups = false;
       
   297         for (int i = loader.loadedClasses.size() - 1; i >= 0 ; i--) {
       
   298             final Object item = loader.loadedClasses.elementAt(i);
       
   299             loader.loadedClasses.removeElementAt(i);
       
   300             if (loader.loadedClasses.contains(item)) {
       
   301                 logln("Resource loaded more than once: "+item);
       
   302                 dups = true;
       
   303             }
       
   304         }
       
   305         if (dups) {
       
   306             errln("ResourceBundle loaded some classes multiple times");
       
   307         }
       
   308     }
       
   309 
       
   310     private class ConcurrentLoadingThread extends Thread {
   232     private class ConcurrentLoadingThread extends Thread {
   311         private Loader loader;
   233         private Loader loader;
   312         public Object bundle;
   234         public Object bundle;
   313         private Bug4168625Getter test;
   235         private Bug4168625Getter test;
   314         private Locale locale;
   236         private Locale locale;
   353 
   275 
   354     /**
   276     /**
   355      * This test ensures that multiple resources can be loading at the same
   277      * This test ensures that multiple resources can be loading at the same
   356      * time as long as they don't depend on each other in some way.
   278      * time as long as they don't depend on each other in some way.
   357      */
   279      */
   358     public void testConcurrentLoading2() throws Exception {
   280     public void testConcurrentLoading() throws Exception {
   359         final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
   281         final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
   360         final Class c = loader.loadClass("Bug4168625Class");
   282         final Class c = loader.loadClass("Bug4168625Class");
   361         final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();
   283         final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();
   362 
   284 
   363         ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "CA"));
   285         ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "CA"));