Author: limpbizkit
Date: Thu Sep 11 21:34:35 2008
New Revision: 619

Modified:
    trunk/src/com/google/inject/Key.java
    trunk/src/com/google/inject/TypeLiteral.java
    trunk/src/com/google/inject/spi/ModuleWriter.java
    trunk/test/com/google/inject/Asserts.java
    trunk/test/com/google/inject/KeyTest.java
    trunk/test/com/google/inject/TypeLiteralTest.java

Log:
Fixing a serialization problem as reported by Ben Yu: TypeLiteral is  
serializable, which causes warnings in anonymous inner type literals.

Modified: trunk/src/com/google/inject/Key.java
==============================================================================
--- trunk/src/com/google/inject/Key.java        (original)
+++ trunk/src/com/google/inject/Key.java        Thu Sep 11 21:34:35 2008
@@ -21,6 +21,8 @@
  import com.google.inject.internal.Annotations;
  import com.google.inject.internal.MoreTypes;
  import com.google.inject.internal.ToStringBuilder;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
  import java.io.Serializable;
  import java.lang.annotation.Annotation;
  import java.lang.reflect.Type;
@@ -503,15 +505,34 @@
    }

    /**
-   * Returns the canonical form of this key for serialization. The returned
-   * instance is always a [EMAIL PROTECTED] Key}, never a subclass. This 
prevents  
problems
-   * caused by serializing anonymous types.
+   * Serializes the key without its type literal, annotation strategy, or
+   * hash code.
     */
-  protected final Object writeReplace() {
-    return getClass() == Key.class
-        ? this
-        : new Key<T>(typeLiteral, annotationStrategy);
+  private static class SerializedForm implements Serializable {
+    final Type type;
+    final Class<? extends Annotation> annotationType;
+    final Annotation annotationInstance;
+
+    SerializedForm(Key<?> key) {
+      this.type = key.getTypeLiteral().getType();
+      this.annotationType = key.getAnnotationType();
+      this.annotationInstance = key.getAnnotation();
+    }
+
+    final Object readResolve() {
+      return annotationInstance != null ? Key.get(type, annotationInstance)
+          : annotationType != null ? Key.get(type, annotationType)
+          : Key.get(type);
+    }
+
+    private static final long serialVersionUID = 0;
+  }
+
+  protected void readObject(ObjectInputStream stream) throws  
InvalidObjectException {
+    throw new InvalidObjectException("Use SerializedForm");
    }

-  private static final long serialVersionUID = 0;
+  protected final Object writeReplace() {
+    return new SerializedForm(this);
+  }
  }

Modified: trunk/src/com/google/inject/TypeLiteral.java
==============================================================================
--- trunk/src/com/google/inject/TypeLiteral.java        (original)
+++ trunk/src/com/google/inject/TypeLiteral.java        Thu Sep 11 21:34:35 2008
@@ -16,12 +16,10 @@

  package com.google.inject;

+import static com.google.common.base.Preconditions.checkNotNull;
  import com.google.inject.internal.MoreTypes;
  import static com.google.inject.internal.MoreTypes.canonicalize;
  import com.google.inject.util.Types;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.Serializable;
  import java.lang.reflect.ParameterizedType;
  import java.lang.reflect.Type;

@@ -42,7 +40,7 @@
   *
   * @author [EMAIL PROTECTED] (Bob Lee)
   */
-public class TypeLiteral<T> implements Serializable {
+public class TypeLiteral<T> {

    final Class<? super T> rawType;
    final Type type;
@@ -143,17 +141,4 @@
    public static <T> TypeLiteral<T> get(Class<T> type) {
      return new TypeLiteral<T>(type);
    }
-
-  /**
-   * Returns the canonical form of this type literal for serialization. The
-   * returned instance is always a [EMAIL PROTECTED] TypeLiteral}, never a 
subclass.  
This
-   * prevents problems caused by serializing anonymous types.
-   */
-  protected final Object writeReplace() {
-    return getClass() == TypeLiteral.class
-        ? this
-        : get(type);
-  }
-
-  private static final long serialVersionUID = 0;
  }

Modified: trunk/src/com/google/inject/spi/ModuleWriter.java
==============================================================================
--- trunk/src/com/google/inject/spi/ModuleWriter.java   (original)
+++ trunk/src/com/google/inject/spi/ModuleWriter.java   Thu Sep 11 21:34:35  
2008
@@ -105,39 +105,39 @@
      }
    }

-  public void writeMessage(final Binder binder, final Message element) {
+  protected void writeMessage(final Binder binder, final Message element) {
      binder.addError(element);
    }

-  public void writeBindInterceptor(final Binder binder, final  
InterceptorBinding element) {
+  protected void writeBindInterceptor(final Binder binder, final  
InterceptorBinding element) {
      List<MethodInterceptor> interceptors = element.getInterceptors();
      binder.withSource(element.getSource()).bindInterceptor(
          element.getClassMatcher(), element.getMethodMatcher(),
          interceptors.toArray(new MethodInterceptor[interceptors.size()]));
    }

-  public void writeBindScope(final Binder binder, final ScopeBinding  
element) {
+  protected void writeBindScope(final Binder binder, final ScopeBinding  
element) {
      binder.withSource(element.getSource()).bindScope(
          element.getAnnotationType(), element.getScope());
    }

-  public void writeRequestInjection(final Binder binder,
+  protected void writeRequestInjection(final Binder binder,
        final InjectionRequest command) {
       
binder.withSource(command.getSource()).requestInjection(command.getInstance());
    }

-  public void writeRequestStaticInjection(final Binder binder,
+  protected void writeRequestStaticInjection(final Binder binder,
        final StaticInjectionRequest element) {
      Class<?> type = element.getType();
      binder.withSource(element.getSource()).requestStaticInjection(type);
    }

-  public void writeConvertToTypes(final Binder binder, final  
TypeConverterBinding element) {
+  protected void writeConvertToTypes(final Binder binder, final  
TypeConverterBinding element) {
      binder.withSource(element.getSource())
          .convertToTypes(element.getTypeMatcher(),  
element.getTypeConverter());
    }

-  public <T> void writeBind(final Binder binder, final Binding<T> element)  
{
+  protected <T> void writeBind(final Binder binder, final Binding<T>  
element) {
      LinkedBindingBuilder<T> lbb =  
binder.withSource(element.getSource()).bind(element.getKey());

      ScopedBindingBuilder sbb = applyTarget(element, lbb);
@@ -147,7 +147,7 @@
    /**
     * Execute this target against the linked binding builder.
     */
-  public <T> ScopedBindingBuilder applyTarget(Binding<T> binding,
+  protected <T> ScopedBindingBuilder applyTarget(Binding<T> binding,
        final LinkedBindingBuilder<T> linkedBindingBuilder) {
      return binding.acceptTargetVisitor(new BindingTargetVisitor<T,  
ScopedBindingBuilder>() {
        public ScopedBindingBuilder visitInstance(T instance,  
Set<InjectionPoint> injectionPoints) {
@@ -187,7 +187,7 @@
      });
    }

-  public void applyScoping(Binding<?> binding, final ScopedBindingBuilder  
scopedBindingBuilder) {
+  protected void applyScoping(Binding<?> binding, final  
ScopedBindingBuilder scopedBindingBuilder) {
      binding.acceptScopingVisitor(new BindingScopingVisitor<Void>() {
        public Void visitEagerSingleton() {
          scopedBindingBuilder.asEagerSingleton();
@@ -211,7 +211,7 @@
      });
    }

-  public <T> void writeGetProvider(final Binder binder, final  
ProviderLookup<T> element) {
+  protected <T> void writeGetProvider(final Binder binder, final  
ProviderLookup<T> element) {
      Provider<T> provider =  
binder.withSource(element.getSource()).getProvider(element.getKey());
      element.initDelegate(provider);
    }

Modified: trunk/test/com/google/inject/Asserts.java
==============================================================================
--- trunk/test/com/google/inject/Asserts.java   (original)
+++ trunk/test/com/google/inject/Asserts.java   Thu Sep 11 21:34:35 2008
@@ -24,6 +24,9 @@
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import junit.framework.Assert;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;

  /**
   * @author [EMAIL PROTECTED] (Jesse Wilson)
@@ -37,11 +40,11 @@
     * for testing the equals method itself.
     */
    public static void assertEqualsBothWays(Object expected, Object actual) {
-    Assert.assertNotNull(expected);
-    Assert.assertNotNull(actual);
-    Assert.assertTrue("expected.equals(actual)", expected.equals(actual));
-    Assert.assertTrue("actual.equals(expected)", actual.equals(expected));
-    Assert.assertEquals("hashCode", expected.hashCode(),  
actual.hashCode());
+    assertNotNull(expected);
+    assertNotNull(actual);
+    assertTrue("expected.equals(actual)", expected.equals(actual));
+    assertTrue("actual.equals(expected)", actual.equals(expected));
+    assertEquals("hashCode", expected.hashCode(), actual.hashCode());
    }

    /**
@@ -49,15 +52,15 @@
     */
    public static void assertContains(String text, String... substrings) {
      int startingFrom = 0;
-    for (int i = 0; i < substrings.length; i++) {
-      int index = text.indexOf(substrings[i], startingFrom);
-      Assert.assertTrue(String.format("Expected \"%s\" to contain  
substring \"%s\"",
-          text, substrings[i]), index >= startingFrom);
-      startingFrom = index + substrings[i].length();
+    for (String substring : substrings) {
+      int index = text.indexOf(substring, startingFrom);
+      assertTrue(String.format("Expected \"%s\" to contain substring  
\"%s\"", text, substring),
+          index >= startingFrom);
+      startingFrom = index + substring.length();
      }

      String lastSubstring = substrings[substrings.length - 1];
-    Assert.assertTrue(String.format("Expected \"%s\" to contain substring  
\"%s\" only once),",
+    assertTrue(String.format("Expected \"%s\" to contain substring \"%s\"  
only once),",
          text, lastSubstring), text.indexOf(lastSubstring, startingFrom) ==  
-1);
    }

@@ -66,42 +69,33 @@
     */
    public static void assertEqualWhenReserialized(Object object)
        throws IOException {
-    Assert.assertTrue("Expected serialVersionUID",  
hasSerialVersionUid(object));
      Object reserialized = reserialize(object);
-    Assert.assertEquals(object, reserialized);
-    Assert.assertEquals(object.hashCode(), reserialized.hashCode());
+    assertEquals(object, reserialized);
+    assertEquals(object.hashCode(), reserialized.hashCode());
    }

    /**
     * Fails unless [EMAIL PROTECTED] object} has the same toString value when  
reserialized.
     */
    public static void assertSimilarWhenReserialized(Object object) throws  
IOException {
-    Assert.assertTrue("Expected serialVersionUID",  
hasSerialVersionUid(object));
      Object reserialized = reserialize(object);
-    Assert.assertEquals(object.toString(), reserialized.toString());
+    assertEquals(object.toString(), reserialized.toString());
    }

-  static boolean hasSerialVersionUid(Object object) {
-    try {
-      return null !=  
object.getClass().getDeclaredField("serialVersionUID");
-    } catch (NoSuchFieldException e) {
-      return false;
-    }
-  }
-
-  static Object reserialize(Object object) throws IOException {
+  public static <E> E reserialize(E original) throws IOException {
      try {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
-      new ObjectOutputStream(out).writeObject(object);
+      new ObjectOutputStream(out).writeObject(original);
        ByteArrayInputStream in = new  
ByteArrayInputStream(out.toByteArray());
-      return new ObjectInputStream(in).readObject();
+      @SuppressWarnings("unchecked") // the reserialized type is assignable
+      E reserialized = (E) new ObjectInputStream(in).readObject();
+      return reserialized;
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }
    }

    public static void assertNotSerializable(Object object) throws  
IOException {
-    Assert.assertFalse("Unexpected serialVersionUID",  
hasSerialVersionUid(object));
      try {
        reserialize(object);
        Assert.fail();

Modified: trunk/test/com/google/inject/KeyTest.java
==============================================================================
--- trunk/test/com/google/inject/KeyTest.java   (original)
+++ trunk/test/com/google/inject/KeyTest.java   Thu Sep 11 21:34:35 2008
@@ -129,7 +129,7 @@
      assertEqualWhenReserialized(Key.get(B[].class));
      assertEqualWhenReserialized(Key.get(new TypeLiteral<Map<List<B>, B>>()  
{}));
      assertEqualWhenReserialized(Key.get(new TypeLiteral<List<B[]>>() {}));
-    assertEqualWhenReserialized(new Key<List<B[]>>() {});
+    assertEquals(new Key<List<B[]>>() {}, Asserts.reserialize(new  
Key<List<B[]>>() {}));
       
assertEqualWhenReserialized(Key.get(Types.listOf(Types.subtypeOf(CharSequence.class))));
    }


Modified: trunk/test/com/google/inject/TypeLiteralTest.java
==============================================================================
--- trunk/test/com/google/inject/TypeLiteralTest.java   (original)
+++ trunk/test/com/google/inject/TypeLiteralTest.java   Thu Sep 11 21:34:35  
2008
@@ -16,8 +16,8 @@

  package com.google.inject;

-import static com.google.inject.Asserts.assertEqualWhenReserialized;
  import static com.google.inject.Asserts.assertEqualsBothWays;
+import static com.google.inject.Asserts.assertNotSerializable;
  import com.google.inject.util.Types;
  import java.io.IOException;
  import java.util.List;
@@ -61,8 +61,8 @@
      assertEqualsBothWays(a, b);
      assertEquals("java.util.List<? extends java.lang.CharSequence>",  
a.toString());
      assertEquals("java.util.List<? extends java.lang.CharSequence>",  
b.toString());
-    assertEqualWhenReserialized(a);
-    assertEqualWhenReserialized(b);
+    assertNotSerializable(a);
+    assertNotSerializable(b);
    }

    public void testMissingTypeParameter() {
@@ -127,6 +127,6 @@
    }

    public void testSerialization() throws IOException {
-    assertEqualWhenReserialized(new TypeLiteral<List<String>>() {});
+    assertNotSerializable(new TypeLiteral<List<String>>() {});
    }
  }

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to