Fix for http://code.google.com/p/google-web-toolkit/issues/detail?id=4814
Fixes a bug with deRPC serialization of boolean values. When a boolean value
is read by the client, it's currently interpreted as a number. When it's
serialized again to the server, it becomes a Double object.
This change adds a test to isolate the issue, and a proposed fix. Instead of
requiring the argument to be written as 'false' to the client, it relaxes what
the server accepts as potential boolean values, allowing 0 or 1 as well.
Review by: robertvawter@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8361 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java b/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java
index c83c00d..9e68812 100644
--- a/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java
+++ b/user/src/com/google/gwt/rpc/server/CommandSerializationUtil.java
@@ -103,8 +103,20 @@
@Override
public void set(Object instance, long offset, Object value) {
- theUnsafe.putBoolean(instance, offset, ((Boolean) value));
+ theUnsafe.putBoolean(instance, offset, toBoolean(value));
}
+
+ private boolean toBoolean(Object value) {
+ if (value instanceof Number) {
+ return ((Number) value).intValue() != 0;
+ } else if (value instanceof String) {
+ return Boolean.valueOf((String) value);
+ } else {
+ // returns false if the value is null.
+ return Boolean.TRUE.equals(value);
+ }
+ }
+
},
BYTE {
@Override
diff --git a/user/test/com/google/gwt/user/client/rpc/InheritanceTest.java b/user/test/com/google/gwt/user/client/rpc/InheritanceTest.java
index eb4a87c..af3d296 100644
--- a/user/test/com/google/gwt/user/client/rpc/InheritanceTest.java
+++ b/user/test/com/google/gwt/user/client/rpc/InheritanceTest.java
@@ -95,6 +95,33 @@
}
/**
+ * Tests that a serialized type can be sent again on the wire.
+ */
+ public void testResendJavaSerializableClass() {
+ final InheritanceTestServiceAsync service = getServiceAsync();
+ final InheritanceTestSetFactory.JavaSerializableClass first =
+ new InheritanceTestSetFactory.JavaSerializableClass(3);
+ AsyncCallback<Object> resendCallback = new AsyncCallback<Object>() {
+ private boolean resend = true;
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Object result) {
+ assertEquals(first, result);
+ if (resend) {
+ resend = false;
+ service.echo((InheritanceTestSetFactory.JavaSerializableClass) result, this);
+ } else {
+ finishTest();
+ }
+ }
+ };
+ delayTestFinishForRpc();
+ service.echo(first, resendCallback);
+ }
+
+ /**
* Test that non-static inner classes are not serializable.
*/
public void testNonStaticInnerClass() {
diff --git a/user/test/com/google/gwt/user/client/rpc/InheritanceTestSetFactory.java b/user/test/com/google/gwt/user/client/rpc/InheritanceTestSetFactory.java
index 19ab5e3..2e11f75 100644
--- a/user/test/com/google/gwt/user/client/rpc/InheritanceTestSetFactory.java
+++ b/user/test/com/google/gwt/user/client/rpc/InheritanceTestSetFactory.java
@@ -72,6 +72,23 @@
public JavaSerializableBaseClass(int field1) {
this.field1 = field1;
}
+
+ @Override
+ public int hashCode() {
+ return field1;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null || obj.getClass() != this.getClass()) {
+ return false;
+ }
+ JavaSerializableBaseClass other = (JavaSerializableBaseClass) obj;
+ return field1 == other.field1;
+ }
}
/**
@@ -79,6 +96,7 @@
*/
public static class JavaSerializableClass extends JavaSerializableBaseClass {
private int field2 = -2;
+ private boolean field3 = true;
public JavaSerializableClass() {
}
@@ -86,6 +104,23 @@
public JavaSerializableClass(int field2) {
this.field2 = field2;
}
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() << 19 + field2;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null || obj.getClass() != this.getClass()) {
+ return false;
+ }
+ JavaSerializableClass other = (JavaSerializableClass) obj;
+ return super.equals(other) && field2 == other.field2 && field3 == other.field3;
+ }
}
/**