Author: [email protected]
Date: Mon Jun 1 22:59:06 2009
New Revision: 5490
Modified:
trunk/user/super/com/google/gwt/emul/java/util/Date.java
trunk/user/test/com/google/gwt/emultest/java/util/DateTest.java
Log:
two changes to java.util.Date in an effort to track down a very intermittent
failure on IE. IE doesn't provide useful stack traces for JS-initiated
exceptions, so all we know is that jsdate is uninitialized or not an object
at some point when it is dereferenced. The changes are:
- use a JSO field storing the JS Date object rather than
making an expando on the underlying object (which
couldn't ever work in hosted mode, but since this is a
JRE emulation class it didn't have to)
- add checks before each dereference of jsdate to see if it has been
mangled;
if so throws a Java exception so we can get a good stack trace.
This does add some overhead, but it shouldn't be too bad. This is a
temporary
change that will be removed once the cause is found.
Patch by: jat
Review by: amitmanjhi, scottb
Modified: trunk/user/super/com/google/gwt/emul/java/util/Date.java
==============================================================================
--- trunk/user/super/com/google/gwt/emul/java/util/Date.java (original)
+++ trunk/user/super/com/google/gwt/emul/java/util/Date.java Mon Jun 1
22:59:06 2009
@@ -15,12 +15,21 @@
*/
package java.util;
+import com.google.gwt.core.client.JavaScriptObject;
+
import java.io.Serializable;
/**
* Represents a date and time.
*/
public class Date implements Cloneable, Comparable<Date>, Serializable {
+
+ /**
+ * JavaScript Date instance.
+ */
+ @SuppressWarnings("unused") // used from JSNI
+ private JavaScriptObject jsdate;
+
/**
* Used only by toString().
*/
@@ -88,6 +97,16 @@
return isNaN(d) ? -1 : d;
}-*/;
+ /**
+ * Throw an exception if jsdate is not an object.
+ *
+ * @param val
+ */
+ @SuppressWarnings("unused") // called by JSNI
+ private static void throwJsDateException(String val) {
+ throw new IllegalStateException("jsdate is " + val);
+ }
+
private static native double utc0(int year, int month, int date, int hrs,
int min, int sec) /*-{
return Date.UTC(year + 1900, month, date, hrs, min, sec);
@@ -147,27 +166,33 @@
}
public native int getDate() /*-{
- return this.jsdate.getDate();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getDate();
}-*/;
public native int getDay() /*-{
- return this.jsdate.getDay();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getDay();
}-*/;
public native int getHours() /*-{
- return this.jsdate.getHours();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getHours();
}-*/;
public native int getMinutes() /*-{
- return this.jsdate.getMinutes();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getMinutes();
}-*/;
public native int getMonth() /*-{
- return this.jsdate.getMonth();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getMonth();
}-*/;
public native int getSeconds() /*-{
- return this.jsdate.getSeconds();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getSeconds();
}-*/;
public long getTime() {
@@ -175,11 +200,13 @@
}
public native int getTimezoneOffset() /*-{
- return this.jsdate.getTimezoneOffset();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getTimezoneOffset();
}-*/;
public native int getYear() /*-{
- return this.jsdate.getFullYear()-1900;
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getFullYear()-1900;
}-*/;
@Override
@@ -188,23 +215,28 @@
}
public native void setDate(int date) /*-{
- this.jsdate.setDate(date);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setDate(date);
}-*/;
public native void setHours(int hours) /*-{
- this.jsdate.setHours(hours);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setHours(hours);
}-*/;
public native void setMinutes(int minutes) /*-{
- this.jsdate.setMinutes(minutes);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setMinutes(minutes);
}-*/;
public native void setMonth(int month) /*-{
- this.jsdate.setMonth(month);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setMonth(month);
}-*/;
public native void setSeconds(int seconds) /*-{
- this.jsdate.setSeconds(seconds);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setSeconds(seconds);
}-*/;
public void setTime(long time) {
@@ -212,14 +244,16 @@
}
public native void setYear(int year) /*-{
- this.jsdate.setFullYear(year + 1900);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setFullYear(year + 1900);
}-*/;
public native String toGMTString() /*-{
- var d = this.jsdate;
+ [email protected]::checkJsDate()();
+ var d = [email protected]::jsdate;
var padTwo = @java.util.Date::padTwo(I);
var month =
- @java.util.Date::monthToString(I)(this.jsdate.getUTCMonth());
+
@java.util.Date::monthToString(I)([email protected]::jsdate.getUTCMonth());
return d.getUTCDate() + " " +
month + " " +
@@ -231,17 +265,19 @@
}-*/;
public native String toLocaleString() /*-{
- return this.jsdate.toLocaleString();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.toLocaleString();
}-*/;
@Override
public native String toString() /*-{
- var d = this.jsdate;
+ [email protected]::checkJsDate()();
+ var d = [email protected]::jsdate;
var padTwo = @java.util.Date::padTwo(I);
var day =
- @java.util.Date::dayToString(I)(this.jsdate.getDay());
+ @java.util.Date::dayToString(I)(d.getDay());
var month =
- @java.util.Date::monthToString(I)(this.jsdate.getMonth());
+ @java.util.Date::monthToString(I)(d.getMonth());
// Compute timezone offset. The value that getTimezoneOffset returns is
// backwards for the transformation that we want.
@@ -259,26 +295,41 @@
+ " " + d.getFullYear();
}-*/;
+ /**
+ * Check that jsdate is valid and throw an exception if not.
+ */
+ @SuppressWarnings("unused") // called by JSNI
+ private native void checkJsDate() /*-{
+ if ([email protected]::jsdate
+ || typeof [email protected]::jsdate != "object") {
+ @java.util.Date::throwJsDateException(Ljava/lang/String;)(""
+ + [email protected]::jsdate);
+ }
+ }-*/;
+
private native double getTime0() /*-{
- return this.jsdate.getTime();
+ [email protected]::checkJsDate()();
+ return [email protected]::jsdate.getTime();
}-*/;
private native void init() /*-{
- this.jsdate = new Date();
+ [email protected]::jsdate = new Date();
}-*/;
private native void init(double date) /*-{
- this.jsdate = new Date(date);
+ [email protected]::jsdate = new Date(date);
}-*/;
private native void init(int year, int month, int date, int hrs, int min,
int sec) /*-{
- this.jsdate = new Date();
- this.jsdate.setFullYear(year + 1900, month, date);
- this.jsdate.setHours(hrs, min, sec, 0);
+ [email protected]::jsdate = new Date();
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setFullYear(year + 1900, month, date);
+ [email protected]::jsdate.setHours(hrs, min, sec, 0);
}-*/;
private native void setTime0(double time) /*-{
- this.jsdate.setTime(time);
+ [email protected]::checkJsDate()();
+ [email protected]::jsdate.setTime(time);
}-*/;
}
Modified: trunk/user/test/com/google/gwt/emultest/java/util/DateTest.java
==============================================================================
--- trunk/user/test/com/google/gwt/emultest/java/util/DateTest.java
(original)
+++ trunk/user/test/com/google/gwt/emultest/java/util/DateTest.java Mon
Jun 1 22:59:06 2009
@@ -32,6 +32,21 @@
public static final String PAST = "PAST";
public static final long SECOND_MILLISECONDS_SHIFT = 10;
+ private static native void mungeDateNull(Date d) /*-{
+ [email protected]::jsdate = null;
+ }-*/;
+
+ private static native void mungeDatePrimitive(Date d) /*-{
+ [email protected]::jsdate = 42;
+ }-*/;
+
+ private static native void mungeDateUndef(Date d) /*-{
+ // use (void 0) to get an undefined value
+ [email protected]::jsdate = (void 0);
+ }-*/;
+
+ Date theDate = new Date();
+
/**
* Sets module name so that javascript compiler can operate.
*/
@@ -94,6 +109,39 @@
assertFalse(a2);
}
+ /**
+ * Test that Date correctly catches when its internal jsdate
+ * instance is mangled.
+ */
+ public void testCheck() {
+ if (GWT.isScript()) {
+ Date d = new Date();
+ mungeDateNull(d);
+ try {
+ d.getHours();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {
+ // do nothing
+ }
+ d = new Date();
+ mungeDateUndef(d);
+ try {
+ d.getHours();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {
+ // do nothing
+ }
+ d = new Date();
+ mungeDatePrimitive(d);
+ try {
+ d.getHours();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {
+ // do nothing
+ }
+ }
+ }
+
/** Testing for public java.lang.Object java.util.Date.clone(). */
public void testClone() {
@@ -303,6 +351,21 @@
assertEquals(110, a2);
}
+ /**
+ * Testing to that if we set the day number to 31 for a month that only
has 30
+ * days in it, that the date rolls over to the first day of the next
month in
+ * sequence.
+ */
+ public void testInvalidDateForMonth() {
+ int monthNum = 3; // April
+ int numDaysInOldMonth = 30;
+ int newDayNum = 31;
+ Date dateWithThirtyDays = new Date(2006, monthNum, 30);
+ dateWithThirtyDays.setDate(newDayNum);
+ assertEquals(dateWithThirtyDays.getMonth(), monthNum + 1);
+ assertEquals(dateWithThirtyDays.getDate(), newDayNum -
numDaysInOldMonth);
+ }
+
/** Testing for public static long
java.util.Date.parse(java.lang.String). */
public void testParse() {
try {
@@ -356,21 +419,6 @@
}
}
- /**
- * Testing to that if we set the day number to 31 for a month that only
has 30
- * days in it, that the date rolls over to the first day of the next
month in
- * sequence.
- */
- public void testInvalidDateForMonth() {
- int monthNum = 3; // April
- int numDaysInOldMonth = 30;
- int newDayNum = 31;
- Date dateWithThirtyDays = new Date(2006, monthNum, 30);
- dateWithThirtyDays.setDate(newDayNum);
- assertEquals(dateWithThirtyDays.getMonth(), monthNum + 1);
- assertEquals(dateWithThirtyDays.getDate(), newDayNum -
numDaysInOldMonth);
- }
-
/** Testing for public void java.util.Date.setHours(int). */
public void testSetHours() {
for (int i = 0; i < 24; i++) {
@@ -380,6 +428,39 @@
}
}
+ /**
+ * We want to test to see that if we are currently in a month with 31
days and
+ * we set the month to one which has less than 31 days, that the month
+ * returned by the date class will be one higher than the month that we
+ * originally set (according to the spec of java.util.date).
+ */
+ public void testSetInvalidMonthForDate() {
+ int dayNum = 31;
+ int newMonthNum = 1;
+ int numDaysInNewMonth = 28;
+ Date dateWithThirtyOneDays = new Date(2006, 12, dayNum);
+ dateWithThirtyOneDays.setMonth(newMonthNum);
+ assertEquals(dateWithThirtyOneDays.getMonth(), newMonthNum + 1);
+ assertEquals(dateWithThirtyOneDays.getDate(), dayNum -
numDaysInNewMonth);
+ }
+
+ /**
+ * We want to test to see that if the date is Feb 29th (in a leap year)
and we
+ * set the year to a non-leap year, that the month and day will roll
over to
+ * March 1st.
+ */
+ public void testSetInvalidYearForDate() {
+ int dayNum = 29;
+ int monthNum = 1; // February
+ int newYearNum = 2005;
+ int numDaysInFebInNewYear = 28;
+ Date leapYearDate = new Date(2004, monthNum, dayNum);
+ leapYearDate.setYear(newYearNum);
+ assertEquals(leapYearDate.getYear(), newYearNum);
+ assertEquals(leapYearDate.getMonth(), monthNum + 1);
+ assertEquals(leapYearDate.getDate(), dayNum - numDaysInFebInNewYear);
+ }
+
/** Testing for public void java.util.Date.setMinutes(int). */
public void testSetMinutes() {
for (int i = 0; i < 24; i++) {
@@ -403,22 +484,6 @@
}
}
- /**
- * We want to test to see that if we are currently in a month with 31
days and
- * we set the month to one which has less than 31 days, that the month
- * returned by the date class will be one higher than the month that we
- * originally set (according to the spec of java.util.date).
- */
- public void testSetInvalidMonthForDate() {
- int dayNum = 31;
- int newMonthNum = 1;
- int numDaysInNewMonth = 28;
- Date dateWithThirtyOneDays = new Date(2006, 12, dayNum);
- dateWithThirtyOneDays.setMonth(newMonthNum);
- assertEquals(dateWithThirtyOneDays.getMonth(), newMonthNum + 1);
- assertEquals(dateWithThirtyOneDays.getDate(), dayNum -
numDaysInNewMonth);
- }
-
/** Testing for public void java.util.Date.setSeconds(int). */
public void testSetSeconds() {
for (int i = 0; i < 24; i++) {
@@ -438,35 +503,6 @@
}
}
- /** Testing for public void java.util.Date.setYear(int). */
- public void testSetYear() {
- for (int i = 1880; i < 2050; i++) {
- // We want to use a fixed date here. If we use the current date, the
- // assertion may fail
- // when the date is February 29th, and we set the year to a non-leap
year
- Date accum0 = new Date(2006, 12, 01);
- accum0.setYear(i);
- assertEquals(accum0.getYear(), i);
- }
- }
-
- /**
- * We want to test to see that if the date is Feb 29th (in a leap year)
and we
- * set the year to a non-leap year, that the month and day will roll
over to
- * March 1st.
- */
- public void testSetInvalidYearForDate() {
- int dayNum = 29;
- int monthNum = 1; // February
- int newYearNum = 2005;
- int numDaysInFebInNewYear = 28;
- Date leapYearDate = new Date(2004, monthNum, dayNum);
- leapYearDate.setYear(newYearNum);
- assertEquals(leapYearDate.getYear(), newYearNum);
- assertEquals(leapYearDate.getMonth(), monthNum + 1);
- assertEquals(leapYearDate.getDate(), dayNum - numDaysInFebInNewYear);
- }
-
/**
* We want to test to see that if the date is Feb 29th (in a leap year)
and we
* set the year to another leap year, that the month and day will be
retained.
@@ -483,6 +519,18 @@
assertEquals(leapYearDate.getDate(), dayNum);
}
+ /** Testing for public void java.util.Date.setYear(int). */
+ public void testSetYear() {
+ for (int i = 1880; i < 2050; i++) {
+ // We want to use a fixed date here. If we use the current date, the
+ // assertion may fail
+ // when the date is February 29th, and we set the year to a non-leap
year
+ Date accum0 = new Date(2006, 12, 01);
+ accum0.setYear(i);
+ assertEquals(accum0.getYear(), i);
+ }
+ }
+
/** Testing for public java.lang.String java.util.Date.toGMTString(). */
public void testToGMTString() {
@@ -618,6 +666,4 @@
private long roundToDay(long accum0) {
return accum0 >> DAY_MILLISECONDS_SHIFT << DAY_MILLISECONDS_SHIFT;
}
-
- Date theDate = new Date();
}
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---