Closed Bug 380005 Opened 18 years ago Closed 18 years ago

Date to String conversion code in NativeDate class is not thread-safe

Categories

(Rhino Graveyard :: Core, defect)

x86
Windows Server 2003
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: gxue, Unassigned)

Details

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.11) Gecko/20070312 Firefox/1.5.0.11 Build Identifier: 1.6R1 Class org.mozilla.javascript.NativeDate class uses static java.text.DateFormat instances (members: timeZoneFormatter,localeDateTimeFormatter,localeDateFormatter, localeTimeFormatter) to convert date/time values to string. However DateFormat instances are not thread-safe (check JDK documentation). This results in occasional runtime exceptions when expressions containing date->string conversion are evaluated concurrently. See Steps to Reproduce for sample code that demonstrates this problem. This code evaluates an expression "Date:" + date_var in 20 concurrent threads. The test code occasionally gives an ArrayIndexOutOfBoundsException. Reproducible: Sometimes Steps to Reproduce: 1.Run the following test code, preferrably on a multi-CPU machine. I've reliably reproduced this on a dual-Intel P4 2.8GHZ machine running Windows 2003 Server, against JRE version 1.5.0_07 2. The program occasionally dumps an exception. See Actual Results for stack. This happens about 1 out of 5 runs in my test. ---- Test Code ---- import java.util.Random; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; public class DateConversionTest { public static void main(String[] args) throws Exception { // Run 10 threads for ( int i = 0; i < 20; i++ ) { Thread t = new TestThread(); t.start(); } } static class TestThread extends Thread { public void run() { Context cx; Scriptable scope; cx = Context.enter(); scope = cx.initStandardObjects(); Random rand = new Random(); for (int i = 0; i < 1000; i++) { int year = rand.nextInt(10) + 1990; int month = rand.nextInt(12) + 1; int day = rand.nextInt(28) + 1; int hour = rand.nextInt(24); int minute = rand.nextInt(60); int sec = rand.nextInt(60); String expr = "\"Date: \" + new Date( " + year + "," + month + "," + day + "," + hour + "," + minute + "," + sec + ")"; cx.evaluateString( scope, expr, "", 1, null ); } Context.exit(); } } } Actual Results: Exception: Exception in thread "Thread-14" java.lang.ArrayIndexOutOfBoundsException: 22 at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(Unknown Source) at java.util.GregorianCalendar.computeFields(Unknown Source) at java.util.GregorianCalendar.computeFields(Unknown Source) at java.util.Calendar.setTimeInMillis(Unknown Source) at java.util.Calendar.setTime(Unknown Source) at java.text.SimpleDateFormat.format(Unknown Source) at java.text.SimpleDateFormat.format(Unknown Source) at java.text.DateFormat.format(Unknown Source) at org.mozilla.javascript.NativeDate.date_format(NativeDate.java:1054) at org.mozilla.javascript.NativeDate.execIdCall(NativeDate.java:201) at org.mozilla.javascript.IdFunctionObject.call(IdFunctionObject.java:121) at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:577) at org.mozilla.javascript.NativeDate.getDefaultValue(NativeDate.java:84) at org.mozilla.javascript.ScriptRuntime.add(ScriptRuntime.java:2290) at org.mozilla.javascript.gen.c2708._c0(:1) at org.mozilla.javascript.gen.c2708.call() at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:304) at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:2769) at org.mozilla.javascript.gen.c2708.call() at org.mozilla.javascript.gen.c2708.exec() at org.mozilla.javascript.Context.evaluateString(Context.java:1220) at DateConversionTest$TestThread.run(DateConversionTest.java:61) Expected Results: No exception Use an instance of DateFormat per thread. Or synchronize code that accesses the static DateFormat instances.
Fixed: Checking in NativeDate.java; /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/NativeDate.java,v <-- NativeDate.java new revision: 1.65.2.1; previous revision: 1.65 done I just synchronized access to the static DateFormat instances.
Status: UNCONFIRMED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Norris - thanks for the fix. Did this fix make it into the 1.6R6 release? Thanks, Gary
You need to log in before you can comment on or make changes to this bug.