|
Description
|
A race condition in ResourceBundle - getBundle/findBundle allows
a resource to be fetched from the cacheList before getBundle finishes
establishing the resource's ancestry.
Under heavy load (many threads) an exception like this occasionally occurs:
java.util.MissingResourceException: Can't find resource for bundle java.text.resources.LocaleElements_en_US, key Eras
at java.util.ResourceBundle.getObject(ResourceBundle.java:322)
at java.text.DateFormatSymbols.initializeData(DateFormatSymbols.java:458)
at java.text.DateFormatSymbols.<init>(DateFormatSymbols.java:109)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:286)
at java.util.Date.toString(Date.java:969)
at Worker.run(Worker.java:22)
I was able to avoid the problem by modifying java.util.ResourceBundle
and synchronizing on cacheList the block of code in getBundle from the
call to findBundle (line 412) to the end of the loop that sets the
ancestry (line 437). However, this approach will cause a lot of contention.
A better solution would be to modify getBundle/findBundle so a
resource is not added to the cacheList until its ancestry is complete.
This program generally reproduces the problem within five invocations.
java testDate
----testDate.java----
import java.util.*;
import java.io.*;
public class testDate {
public static void main(String[] args) {
synchronized (Worker.mo_lock) {
for (int x = 0; x < 2000; x ++ ) {
Worker w = new Worker ();
w.start ();
}
//Worker.mo_lock.notifyAll ();
System.out.println ("Beginning test");
}
try {
while (true) {
Thread.sleep (15000);
System.out.println ("Beginning Synch sequence...");
synchronized (Worker.mo_lock) {
System.out.println ("Synching...");
Worker.mb_synch = true;
Thread.sleep (10000);
System.gc ();
Worker.mb_synch = false;
int li_count = Worker.mi_numCalls;
System.out.println ("Synching complete, "
+ li_count + " threads synched.");
}
}
} catch (InterruptedException po) {}
}
}
-----------------------------
----Worker.java----
import java.util.*;
public class Worker extends Thread {
static Object mo_lock = new Object ();
static public boolean mb_synch = false;
static public int mi_numCalls = 0;
public Worker () {
}
static void foo () {
mi_numCalls ++;
synchronized (mo_lock) {
mi_numCalls = 0;
}
}
public void run () {
try {
foo ();
String foo;
for (int y=0;y < 1000;y++) {
for (int x=0;x < 10;x++) {
foo = new Date ().toString ();
}
// System.gc ();
if (mb_synch) foo ();
}
} catch (RuntimeException e) {
e.printStackTrace ();
System.exit (1);
// } catch (java.lang.InterruptedException e) {
}
}
}
----------------------------------
Warning: This program spawns 2000 threads. It can drive the
load on a 2 x Sparc 300Mhz system w/ 500MB RAM well over 30.
It's greatest chance of reproducing the test is within the first
30 seconds after printing "Beginning test." If nothing happens
I recommend you terminate it and run it again, that should keep
the load from getting real high.
------------------------------------
java -version:
java version "1.2.2"
HotSpot VM (1.0.1, mixed mode, build a)
java -fullversion
java full version "JDK-1.2.2-U"
------------------------------------
Modifying the exception thown in getObject at line 319 like this:
throw new MissingResourceException("Can't find resource "
+ key + " in " + this.getClass().getName()
+ " parent = " + ((parent == null) ? "null"
: parent.getClass ().getName ()),
this.getClass().getName() ,
key);
will show that resources are indeed being used without ancestry:
java.util.MissingResourceException: Can't find resource Eras in java.text.resources.LocaleElements_en_US parent = null
at java.util.ResourceBundle.getObject(ResourceBundle.java:320)
at java.text.DateFormatSymbols.initializeData(DateFormatSymbols.java:458)
at java.text.DateFormatSymbols.<init>(DateFormatSymbols.java:109)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:286)
at java.util.Date.toString(Date.java:969)
at Worker.run(Worker.java:22)
I hope this is enough info to get the problem fixed. Looks like it
has been around for a while (see bug# 4175900).
Currently we are seeing this in the servlet engine we are using.
It is including the current timestamp in its log file, this
exception shows up when we do load testing (we are not in production yet)
(Review ID: 93238)
======================================================================
There seems to be a threading/scalability problem with
HotSpot/JDK.
I have a Java server application that processes through hunderds
of thousands records an hour. It is a long running process that
performs a lot of database I/O and performs a lot of number
crunching. The program is highly threaded. There are typically
8-15 database connections open each with their own Java thread.
I am running under the following configuration:
*Solaris 5.7 - with all recommending HotSpot patches
*Sun Ultra 4 hardware - with 4 processors installed, 500M memory
*HotSport 1.0.1
The problem has occured with the default HotSpot setting and
with the following setting:
java -Xmx160m -Xconcurrentio -Xbatch
*JDK 1.2.2
Every few thousand records I get the following exception:
java.util.MissingResourceException: Can't find resource for bundle java.text.resources.LocaleElements_en, key Eras
at java.util.ResourceBundle.getObject(ResourceBundle.java:322)
at java.util.ResourceBundle.getObject(ResourceBundle.java:319)
at java.text.DateFormatSymbols.initializeData(DateFormatSymbols.java:458)
at java.text.DateFormatSymbols.<init>(DateFormatSymbols.java:109)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:286)
at com.informix.util.dateUtil.formatDate(dateUtil.java:957)
at com.informix.util.dateUtil.getdbDateStr(dateUtil.java:409)
at com.informix.util.dateUtil.convertDateStr(dateUtil.java:2596)
at com.informix.jdbc.IfxDate.toString(IfxDate.java:130)
at com.informix.jdbc.IfxResultSet.getString(IfxResultSet.java:526)
at com.informix.jdbc.IfxResultSet.getString(IfxResultSet.java:550)
at com.eease.lib.edbc.Query.getString(Query.java)
The problem happens consistently every few thousand records but
without any reason and at different points in the application.
The application performs a lot of Date to String conversion
in each of the many threads. The problem seems to occur more
often when the application has more threads open and processing.
This bug is causing me great pain. I am really excited about
the performance of HotSpot but this is a serious scalability
problem with the VM.
There are also a few posting the the java.lang.* news groups
where xxxxx people have had similar problems with this
MissingResourceException.
I look forward to hearing back from you.
Sincerely,
Sam Taha
(Review ID: 95586)
-------------------
> Hello Mark,
>
> I believe my problem is related directly to bug ID = 4261469.
> The submitter of that bug has a similar code sample to
> yours but his loop is more intensive than yours and he says it
> only happens 1 out of 5 times he runs his code sample.
>
> I consistently(just about every time) encounter this exception
> when I switch my server to use threading. When I turn
> off threading and do all my database operations
> (where the date to string conversion is being called)
> in a serial manner I dont see the exception at all.
>
> However, I did find a way around the problem that
> supports the existence of the bug. I reworked my code so that each
> thread creates its own java.text.SimpleDateFormat object
> that is used during the life of the thread and used through
> out the thread for all date to string conversion.
> With that the exception no longer happens.
>
> Hope this helps.
>
> Sam Taha
Date: Wed, 29 Sep 1999 08:14:18 -0400
Subject: Re: (Review ID: 95586) MissingResourceException in Heavily Threaded Server
When a java.*.Date.toString() is called it creates its own new
java.text.SimpleDateFormat object that eventually calls down to the
java.util.ResourceBundle class. That is where the race condition appears to exist in the ResourceBundle class. The stack dump from my exeception shows the location. By creating a single SimpleDateFormater per thread I avoid having to call down the ResourceBundle class but once when instantiating the class.
Note that I am running my Java application on a 4 processor SUN machine and the person the reported the bug ID=4261469 was also running it on a 2 processor box.
======================================================================
|