simplify the java syncbase put/get API

<T> ListenableFuture<T> get(VContext context, Class<T> clazz);
ListenableFuture<Void> put(VContext context, Object value);

Change-Id: I7ff446a42cef03d4eb49a0966db28d21f9456a15
diff --git a/lib/src/main/java/io/v/impl/google/rpc/ServerRPCHelper.java b/lib/src/main/java/io/v/impl/google/rpc/ServerRPCHelper.java
index 4fdc4ee..26824dc 100644
--- a/lib/src/main/java/io/v/impl/google/rpc/ServerRPCHelper.java
+++ b/lib/src/main/java/io/v/impl/google/rpc/ServerRPCHelper.java
@@ -41,7 +41,7 @@
                     public ListenableFuture<byte[][]> apply(VdlValue[] tags) throws Exception {
                         byte[][] vomTags = new byte[tags.length][];
                         for (int i = 0; i < tags.length; ++i) {
-                            vomTags[i] = VomUtil.encode(tags[i]);
+                            vomTags[i] = VomUtil.encode(tags[i], tags[i].vdlType());
                         }
                         return Futures.immediateFuture(vomTags);
                     }
diff --git a/lib/src/main/java/io/v/v23/syncbase/Collection.java b/lib/src/main/java/io/v/v23/syncbase/Collection.java
index 8b68966..30d5780 100644
--- a/lib/src/main/java/io/v/v23/syncbase/Collection.java
+++ b/lib/src/main/java/io/v/v23/syncbase/Collection.java
@@ -12,7 +12,6 @@
 import io.v.v23.services.syncbase.KeyValue;
 
 import javax.annotation.CheckReturnValue;
-import java.lang.reflect.Type;
 
 /**
  * Interface for a database collection, i.e., a collection of {@link Row}s.
@@ -129,10 +128,10 @@
      *
      * @param context Vanadium context
      * @param key     the primary key for a row
-     * @param type    type of the value to be returned (needed for de-serialization)
+     * @param clazz   the Class to instantiate, populate during de-serialization, and return
      */
     @CheckReturnValue
-    ListenableFuture<Object> get(VContext context, String key, Type type);
+    <T> ListenableFuture<T> get(VContext context, String key, Class<T> clazz);
 
     /**
      * Writes the value to the collection under the provided primary key.
@@ -145,11 +144,10 @@
      *
      * @param context Vanadium context
      * @param key     primary key under which the value is to be written
-     * @param type    type of the value to be returned (needed for serialization)
      * @param value   value to be written
      */
     @CheckReturnValue
-    ListenableFuture<Void> put(VContext context, String key, Object value, Type type);
+    ListenableFuture<Void> put(VContext context, String key, Object value);
 
     /**
      * Deletes the value for the given primary key.
diff --git a/lib/src/main/java/io/v/v23/syncbase/CollectionImpl.java b/lib/src/main/java/io/v/v23/syncbase/CollectionImpl.java
index 806f092..ac33577 100644
--- a/lib/src/main/java/io/v/v23/syncbase/CollectionImpl.java
+++ b/lib/src/main/java/io/v/v23/syncbase/CollectionImpl.java
@@ -17,8 +17,6 @@
 
 import io.v.v23.syncbase.util.Util;
 
-import java.lang.reflect.Type;
-
 class CollectionImpl implements Collection {
 
     private final String fullName;
@@ -74,13 +72,13 @@
     }
 
     @Override
-    public ListenableFuture<Object> get(VContext ctx, String key, Type type) {
-        return getRow(key).get(ctx, type);
+    public <T>ListenableFuture<T> get(VContext ctx, String key, Class<T> clazz) {
+        return getRow(key).get(ctx, clazz);
     }
 
     @Override
-    public ListenableFuture<Void> put(VContext ctx, String key, Object value, Type type) {
-        return getRow(key).put(ctx, value, type);
+    public ListenableFuture<Void> put(VContext ctx, String key, Object value) {
+        return getRow(key).put(ctx, value);
     }
 
     @Override
diff --git a/lib/src/main/java/io/v/v23/syncbase/DatabaseImpl.java b/lib/src/main/java/io/v/v23/syncbase/DatabaseImpl.java
index cbb0d2d..31fb3cf 100644
--- a/lib/src/main/java/io/v/v23/syncbase/DatabaseImpl.java
+++ b/lib/src/main/java/io/v/v23/syncbase/DatabaseImpl.java
@@ -40,7 +40,6 @@
 import io.v.v23.verror.VException;
 import io.v.v23.vom.VomUtil;
 
-import java.io.Serializable;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -306,7 +305,7 @@
             this.input = input;
             this.columnNames = new ArrayList<>(columnNames.size());
             for (int i = 0; i < columnNames.size(); ++i) {
-                Serializable elem = columnNames.get(i).getElem();
+                Object elem = columnNames.get(i).getElem();
                 if (elem instanceof String) {
                     this.columnNames.add((String) elem);
                 } else {
diff --git a/lib/src/main/java/io/v/v23/syncbase/Row.java b/lib/src/main/java/io/v/v23/syncbase/Row.java
index 64ab768..a5bbe74 100644
--- a/lib/src/main/java/io/v/v23/syncbase/Row.java
+++ b/lib/src/main/java/io/v/v23/syncbase/Row.java
@@ -7,7 +7,6 @@
 import io.v.v23.context.VContext;
 
 import javax.annotation.CheckReturnValue;
-import java.lang.reflect.Type;
 
 /**
  * A handle for a single row in a {@link Collection}.
@@ -64,9 +63,11 @@
      * {@code context} gets canceled.
      *
      * @param context Vanadium context
+     * @param clazz   the Class to instantiate, populate during de-serialization, and return
+     * @return
      */
     @CheckReturnValue
-    ListenableFuture<Object> get(VContext context, Type type);
+    <T> ListenableFuture<T> get(VContext context, Class<T> clazz);
 
     /**
      * Writes the given value for this row.
@@ -81,5 +82,5 @@
      * @param value   value to write
      */
     @CheckReturnValue
-    ListenableFuture<Void> put(VContext context, Object value, Type type);
+    ListenableFuture<Void> put(VContext context, Object value);
 }
diff --git a/lib/src/main/java/io/v/v23/syncbase/RowImpl.java b/lib/src/main/java/io/v/v23/syncbase/RowImpl.java
index 03ba47c..b7763bb 100644
--- a/lib/src/main/java/io/v/v23/syncbase/RowImpl.java
+++ b/lib/src/main/java/io/v/v23/syncbase/RowImpl.java
@@ -15,11 +15,8 @@
 import io.v.v23.services.syncbase.RowClientFactory;
 import io.v.v23.syncbase.util.Util;
 import io.v.v23.vdl.VdlAny;
-import io.v.v23.verror.VException;
 import io.v.v23.vom.VomUtil;
 
-import java.lang.reflect.Type;
-
 class RowImpl implements Row {
     private final String fullName;
     private final String key;
@@ -56,22 +53,20 @@
     }
 
     @Override
-    public ListenableFuture<Object> get(VContext ctx, final Type type) {
+    public <T> ListenableFuture<T> get(VContext ctx, final Class<T> clazz) {
         return VFutures.withUserLandChecks(ctx, Futures.transform(client.get(ctx, this.batchHandle),
-                new AsyncFunction<VdlAny, Object>() {
+                new AsyncFunction<VdlAny, T>() {
                     @Override
-                    public ListenableFuture<Object> apply(VdlAny vdlAny) throws Exception {
-                        return Futures.immediateFuture(VomUtil.decode(VomUtil.encode(vdlAny), type));
+                    public ListenableFuture<T> apply(VdlAny vdlAny) throws Exception {
+                        final byte[] encodedBytes = VomUtil.encode(vdlAny, VdlAny.VDL_TYPE);
+                        final Object decodedObject = VomUtil.decode(encodedBytes, clazz);
+                        return Futures.immediateFuture((T) decodedObject);
                     }
                 }));
     }
 
     @Override
-    public ListenableFuture<Void> put(VContext ctx, Object value, Type type) {
-        try {
-            return client.put(ctx, this.batchHandle, (VdlAny) VomUtil.decode(VomUtil.encode(value, type), VdlAny.class));
-        } catch (VException e) {
-            return VFutures.withUserLandChecks(ctx, Futures.<Void>immediateFailedFuture(e));
-        }
+    public ListenableFuture<Void> put(VContext ctx, Object value) {
+        return client.put(ctx, this.batchHandle, new VdlAny(value.getClass(), value));
     }
 }
diff --git a/lib/src/main/java/io/v/v23/vdl/VdlAny.java b/lib/src/main/java/io/v/v23/vdl/VdlAny.java
index 28cd176..029a9f4 100644
--- a/lib/src/main/java/io/v/v23/vdl/VdlAny.java
+++ b/lib/src/main/java/io/v/v23/vdl/VdlAny.java
@@ -4,7 +4,6 @@
 
 package io.v.v23.vdl;
 
-import java.io.Serializable;
 import java.lang.reflect.Type;
 import java.lang.reflect.Array;
 import java.util.Arrays;
@@ -21,16 +20,16 @@
   */
   public static final io.v.v23.vdl.VdlType VDL_TYPE = io.v.v23.vdl.Types.ANY;
 
-  private final Serializable elem;
+  private final Object elem;
   private final VdlType elemType;
 
-  public VdlAny(VdlType vdlType, Serializable value) {
+  public VdlAny(VdlType vdlType, Object value) {
     super(Types.ANY);
     elem = value;
     elemType = vdlType;
   }
 
-  public VdlAny(Type type, Serializable value) {
+  public VdlAny(Type type, Object value) {
     this(Types.getVdlTypeFromReflect(type), value);
   }
 
@@ -42,7 +41,7 @@
     this((VdlType) null, null);
   }
 
-  public Serializable getElem() {
+  public Object getElem() {
     return elem;
   }
 
diff --git a/lib/src/main/java/io/v/v23/verror/VException.java b/lib/src/main/java/io/v/v23/verror/VException.java
index 6950ed1..bdaeaed 100644
--- a/lib/src/main/java/io/v/v23/verror/VException.java
+++ b/lib/src/main/java/io/v/v23/verror/VException.java
@@ -326,7 +326,7 @@
     }
 
     private final IDAction id;  // non-null
-    private final Serializable[] params;  // non-null
+    private final Object[] params;  // non-null
     private final VdlType[] paramTypes;  // non-null, same length as params
 
     /**
@@ -391,7 +391,7 @@
                 opName, params, convertParamTypes(paramTypes)));
     }
 
-    VException(IDAction id, String msg, Serializable[] params, VdlType[] paramTypes) {
+    VException(IDAction id, String msg, Object[] params, VdlType[] paramTypes) {
         super(msg);
         this.id = id;
         this.params = params;
@@ -473,7 +473,7 @@
         return this.id.hashCode();
     }
 
-    Serializable[] getParams() { return this.params; }
+    Object[] getParams() { return this.params; }
 
     VdlType[] getParamTypes() { return this.paramTypes; }
 }
diff --git a/lib/src/main/java/io/v/v23/verror/VExceptionVdlConverter.java b/lib/src/main/java/io/v/v23/verror/VExceptionVdlConverter.java
index d8f817c..0db59b8 100644
--- a/lib/src/main/java/io/v/v23/verror/VExceptionVdlConverter.java
+++ b/lib/src/main/java/io/v/v23/verror/VExceptionVdlConverter.java
@@ -13,7 +13,6 @@
 import io.v.v23.vdl.WireRetryCode;
 import io.v.v23.verror.VException.ActionCode;
 
-import java.io.Serializable;
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
 import java.util.List;
@@ -43,7 +42,7 @@
         assertInstanceOf(nativeValue, VException.class);
         VException e = (VException) nativeValue;
         List<VdlAny> paramVals = new ArrayList<VdlAny>();
-        Serializable[] params = e.getParams();
+        Object[] params = e.getParams();
         VdlType[] paramTypes = e.getParamTypes();
         for (int i = 0; i < params.length; ++i) {
             if (paramTypes[i] == null) {
@@ -62,7 +61,7 @@
                 VException.ActionCode.fromValue(error.getRetryCode().ordinal()));
 
         List<VdlAny> paramVals = error.getParamList();
-        Serializable[] params = new Serializable[paramVals.size()];
+        Object[] params = new Object[paramVals.size()];
         VdlType[] paramTypes = new VdlType[paramVals.size()];
         for (int i = 0; i < paramVals.size(); ++i) {
             VdlAny paramVal = paramVals.get(i);
diff --git a/lib/src/main/java/io/v/v23/vom/BinaryDecoder.java b/lib/src/main/java/io/v/v23/vom/BinaryDecoder.java
index 29ec7a7..f1d1df4 100644
--- a/lib/src/main/java/io/v/v23/vom/BinaryDecoder.java
+++ b/lib/src/main/java/io/v/v23/vom/BinaryDecoder.java
@@ -25,7 +25,6 @@
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Type;
@@ -203,7 +202,7 @@
         // Solve any/optional case.
         if (actualType.getKind() != Kind.ANY && actualType.getKind() != Kind.OPTIONAL) {
             if (target.getKind() == Kind.ANY) {
-                return new VdlAny(actualType, (Serializable) readValue(actualType, Object.class));
+                return new VdlAny(actualType, readValue(actualType, Object.class));
             } else if (target.getKind() == Kind.OPTIONAL) {
                 Type elemType = ReflectUtil.getElementType(target.getTargetType(), 0);
                 return VdlOptional.of((VdlValue) readValue(actualType, elemType));
@@ -286,7 +285,7 @@
         }
         VdlType actualType = getType(new TypeId(typeId));
         if (target.getKind() == Kind.ANY) {
-            return new VdlAny(actualType, (Serializable) readValue(actualType, Object.class));
+            return new VdlAny(actualType, readValue(actualType, Object.class));
         } else {
             Type targetType = target.getTargetType();
             assertTypesCompatible(actualType, targetType);
diff --git a/lib/src/main/java/io/v/v23/vom/VomUtil.java b/lib/src/main/java/io/v/v23/vom/VomUtil.java
index 1be910c..b157eee 100644
--- a/lib/src/main/java/io/v/v23/vom/VomUtil.java
+++ b/lib/src/main/java/io/v/v23/vom/VomUtil.java
@@ -92,7 +92,6 @@
         return out.toByteArray();
     }
 
-
     /**
      * VOM-decodes the provided data using a new VOM-decoder.
      *
diff --git a/lib/src/test/java/io/v/v23/syncbase/SyncbaseTest.java b/lib/src/test/java/io/v/v23/syncbase/SyncbaseTest.java
index ce5810f..1a93c36 100644
--- a/lib/src/test/java/io/v/v23/syncbase/SyncbaseTest.java
+++ b/lib/src/test/java/io/v/v23/syncbase/SyncbaseTest.java
@@ -6,6 +6,7 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 import com.google.common.io.ByteStreams;
 import com.google.common.io.Files;
 import com.google.common.util.concurrent.Futures;
@@ -20,6 +21,7 @@
 import io.v.v23.rpc.ListenSpec;
 import io.v.v23.rpc.Server;
 import io.v.v23.security.BlessingPattern;
+import io.v.v23.security.Caveat;
 import io.v.v23.security.access.AccessList;
 import io.v.v23.security.access.Constants;
 import io.v.v23.security.access.Permissions;
@@ -48,6 +50,7 @@
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Random;
 
 import static com.google.common.truth.Truth.assertThat;
 import static io.v.v23.VFutures.sync;
@@ -60,6 +63,8 @@
     private static final String COLLECTION_NAME = "collection";
     private static final Id COLLECTION_ID = new Id("v.io:u:sam", COLLECTION_NAME);
     private static final String ROW_NAME = "row/a#%b";  // symbols are okay
+    private static final String ROW_NAME2 = "row/a#%c";  // symbols are okay
+    private static final String ROW_NAME3 = "row/a#%d";  // symbols are okay
 
     private VContext ctx;
     private Permissions allowAll;
@@ -134,13 +139,13 @@
         assertThat(sync(db.listCollections(ctx))).containsExactly(COLLECTION_ID);
 
         assertThat(sync(collection.getRow("row1").exists(ctx))).isFalse();
-        sync(collection.put(ctx, "row1", "value1", String.class));
+        sync(collection.put(ctx, "row1", "value1"));
         assertThat(sync(collection.getRow("row1").exists(ctx))).isTrue();
         assertThat(sync(collection.get(ctx, "row1", String.class))).isEqualTo("value1");
         sync(collection.delete(ctx, "row1"));
         assertThat(sync(collection.getRow("row1").exists(ctx))).isFalse();
-        sync(collection.put(ctx, "row1", "value1", String.class));
-        sync(collection.put(ctx, "row2", "value2", String.class));
+        sync(collection.put(ctx, "row1", "value1"));
+        sync(collection.put(ctx, "row2", "value2"));
         assertThat(sync(collection.getRow("row1").exists(ctx))).isTrue();
         assertThat(sync(collection.getRow("row2").exists(ctx))).isTrue();
         assertThat(sync(collection.get(ctx, "row1", String.class))).isEqualTo("value1");
@@ -158,6 +163,55 @@
         assertThat(sync(db.listCollections(ctx))).isEmpty();
     }
 
+    public static class MyTestClass {
+        String foo;
+        Integer bar;
+        List<String> baz;
+
+        public MyTestClass() {
+            foo = null;
+            bar = null;
+            baz = Lists.newArrayList();
+        }
+
+        public MyTestClass(String inFoo, Integer inBar, String ... inBaz) {
+            foo = null;
+            bar = null;
+            baz = Lists.newArrayList();
+            for (String value : inBaz) {
+                baz.add(value);
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof MyTestClass)) {
+                return false;
+            }
+
+            MyTestClass that = (MyTestClass) o;
+
+            if (foo != null ? !foo.equals(that.foo) : that.foo != null) {
+                return false;
+            }
+            if (bar != null ? !bar.equals(that.bar) : that.bar != null) {
+                return false;
+            }
+            return baz.equals(that.baz);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = foo != null ? foo.hashCode() : 0;
+            result = 31 * result + (bar != null ? bar.hashCode() : 0);
+            result = 31 * result + baz.hashCode();
+            return result;
+        }
+    }
+
     public void testRow() throws Exception {
         Collection collection = createCollection(createDatabase(createService()));
         Row row = collection.getRow(ROW_NAME);
@@ -167,16 +221,35 @@
                 NamingUtil.join(serverEndpoint.name(), Util.encodeId(DB_ID),
                         Util.encodeId(COLLECTION_ID), Util.encode(ROW_NAME)));
         assertThat(sync(row.exists(ctx))).isFalse();
-        sync(row.put(ctx, "value", String.class));
+        sync(row.put(ctx, "value"));
         assertThat(sync(row.exists(ctx))).isTrue();
         assertThat(sync(row.get(ctx, String.class))).isEqualTo("value");
         assertThat(sync(collection.get(ctx, ROW_NAME, String.class))).isEqualTo("value");
         sync(row.delete(ctx));
         assertThat(sync(row.exists(ctx))).isFalse();
-        sync(collection.put(ctx, ROW_NAME, "value", String.class));
+
+        // String
+        sync(collection.put(ctx, ROW_NAME, "value"));
         assertThat(sync(row.exists(ctx))).isTrue();
         assertThat(sync(row.get(ctx, String.class))).isEqualTo("value");
         assertThat(sync(collection.get(ctx, ROW_NAME, String.class))).isEqualTo("value");
+
+        // Integer
+        sync(collection.put(ctx, ROW_NAME3, 42));
+        assertThat(sync(collection.get(ctx, ROW_NAME3, Integer.class))).isEqualTo(42);
+
+        // Java POJO, MyTestClass
+        MyTestClass mtc = new MyTestClass("hello", 58501, "a", "b", "c");
+        sync(collection.put(ctx, ROW_NAME2, mtc));
+        assertThat(sync(collection.get(ctx, ROW_NAME2, MyTestClass.class))).isEqualTo(mtc);
+
+        // VDL-generated class, Caveat
+        Random random = new Random();
+        byte[] idBytes = new byte[16];
+        random.nextBytes(idBytes);
+        Caveat caveat = new Caveat(new io.v.v23.uniqueid.Id(idBytes), "voms".getBytes());
+        sync(collection.put(ctx, ROW_NAME2, caveat));
+        assertThat(sync(collection.get(ctx, ROW_NAME2, Caveat.class))).isEqualTo(caveat);
     }
 
     public void testDatabaseExec() throws Exception {
@@ -186,9 +259,9 @@
         Bar bar = new Bar(0.5f, "b");
         Baz baz = new Baz("John Doe", true);
 
-        sync(collection.put(ctx, "foo", foo, Foo.class));
-        sync(collection.put(ctx, "bar", bar, Bar.class));
-        sync(collection.put(ctx, "baz", baz, Baz.class));
+        sync(collection.put(ctx, "foo", foo));
+        sync(collection.put(ctx, "bar", bar));
+        sync(collection.put(ctx, "baz", baz));
 
         {
             DatabaseCore.QueryResults results = sync(db.exec(ctx,
@@ -228,9 +301,9 @@
         Baz baz = new Baz("John Doe", true);
         ResumeMarker marker = sync(db.getResumeMarker(ctx));
 
-        sync(collection.put(ctx, "foo", foo, Foo.class));
-        sync(collection.put(ctx, "bar", bar, Bar.class));
-        sync(collection.put(ctx, "baz", baz, Baz.class));
+        sync(collection.put(ctx, "foo", foo));
+        sync(collection.put(ctx, "bar", bar));
+        sync(collection.put(ctx, "baz", baz));
         sync(collection.getRow("baz").delete(ctx));
         ImmutableList<WatchChange> expectedChanges = ImmutableList.of(
                 new WatchChange(COLLECTION_ID, "bar", ChangeType.PUT_CHANGE,
@@ -253,9 +326,9 @@
         Bar bar = new Bar(0.5f, "b");
         Baz baz = new Baz("John Doe", true);
 
-        sync(collection.put(ctx, "foo", foo, Foo.class));
-        sync(collection.put(ctx, "barfoo", foo, Foo.class));
-        sync(collection.put(ctx, "bar", bar, Bar.class));
+        sync(collection.put(ctx, "foo", foo));
+        sync(collection.put(ctx, "barfoo", foo));
+        sync(collection.put(ctx, "bar", bar));
 
         VContext ctxC = ctx.withCancel();
         Iterator<WatchChange> it = InputChannels.asIterable(
@@ -268,7 +341,7 @@
                         new VdlAny(Foo.class, foo), null, false, false));
         checkWatch(it, expectedInitialChanges);
 
-        sync(collection.put(ctx, "baz", baz, Baz.class));
+        sync(collection.put(ctx, "baz", baz));
         sync(collection.getRow("baz").delete(ctx));
 
         ImmutableList<WatchChange> expectedChanges = ImmutableList.of(
@@ -308,7 +381,7 @@
         BatchDatabase batchFoo = sync(db.beginBatch(ctx, null));
         Collection batchFooCollection = batchFoo.getCollection(COLLECTION_ID);
         assertThat(sync(batchFooCollection.exists(ctx))).isTrue();
-        sync(batchFooCollection.put(ctx, ROW_NAME, "foo", String.class));
+        sync(batchFooCollection.put(ctx, ROW_NAME, "foo"));
         // Assert that value is visible inside the batch but not outside.
         assertThat(sync(batchFooCollection.get(ctx, ROW_NAME, String.class))).isEqualTo("foo");
         assertThat(sync(collection.getRow(ROW_NAME).exists(ctx))).isFalse();
@@ -316,7 +389,7 @@
         BatchDatabase batchBar = sync(db.beginBatch(ctx, null));
         Collection batchBarCollection = batchBar.getCollection(COLLECTION_ID);
         assertThat(sync(batchBarCollection.exists(ctx))).isTrue();
-        sync(batchBarCollection.put(ctx, ROW_NAME, "foo", String.class));
+        sync(batchBarCollection.put(ctx, ROW_NAME, "foo"));
         // Assert that value is visible inside the batch but not outside.
         assertThat(sync(batchBarCollection.get(ctx, ROW_NAME, String.class))).isEqualTo("foo");
         assertThat(sync(collection.getRow(ROW_NAME).exists(ctx))).isFalse();
@@ -355,10 +428,10 @@
                     }
                     // If we need to fail the commit, write to foo in a separate concurrent batch.
                     if (retries < 2) {
-                        sync(d.getCollection(COLLECTION_ID).put(ctx, fooKey, "foo", String.class));
+                        sync(d.getCollection(COLLECTION_ID).put(ctx, fooKey, "foo"));
                     }
                     // Write to bar.
-                    sync(b.getCollection(COLLECTION_ID).put(ctx, barKey, "bar", String.class));
+                    sync(b.getCollection(COLLECTION_ID).put(ctx, barKey, "bar"));
                 } catch (VException e) {
                     return Futures.immediateFailedFuture(e);
                 }
@@ -376,7 +449,7 @@
     public void testRunInBatchReadOnly() throws Exception {
         final Database d = createDatabase(createService());
         Collection collection = createCollection(d);
-        sync(collection.put(ctx, "foo", "foo", String.class));
+        sync(collection.put(ctx, "foo", "foo"));
 
         sync(Batch.runInBatch(ctx, d, new BatchOptions("", true), new Batch.BatchOperation() {
             @Override
@@ -386,7 +459,7 @@
                     Object before = sync(b.getCollection(COLLECTION_ID).get(ctx, "foo", String.class));
                     // Write to foo in a separate concurrent batch. It should not cause a retry
                     // since readonly batches are not committed.
-                    sync(d.getCollection(COLLECTION_ID).put(ctx, "foo", "oof", String.class));
+                    sync(d.getCollection(COLLECTION_ID).put(ctx, "foo", "oof"));
                     // Read foo again. Batch should not see the changed value.
                     Object after = sync(b.getCollection(COLLECTION_ID).get(ctx, "foo", String.class));
                     if (!before.equals(after)) {
@@ -394,7 +467,7 @@
                     }
                     // Try writing to bar. This should fail since the batch is readonly.
                     try {
-                        sync(b.getCollection(COLLECTION_ID).put(ctx, "bar", "bar", String.class));
+                        sync(b.getCollection(COLLECTION_ID).put(ctx, "bar", "bar"));
                         throw new VException("Expected b.put() to fail with ReadOnlyBatchException");
                     } catch (ReadOnlyBatchException e) {
                         // ok
diff --git a/lib/src/test/java/io/v/v23/vom/BinaryDecoderTest.java b/lib/src/test/java/io/v/v23/vom/BinaryDecoderTest.java
index 2b6fb63..71e1fcf 100644
--- a/lib/src/test/java/io/v/v23/vom/BinaryDecoderTest.java
+++ b/lib/src/test/java/io/v/v23/vom/BinaryDecoderTest.java
@@ -22,7 +22,6 @@
 import io.v.v23.vdl.VdlValue;
 import io.v.v23.verror.VException;
 
-import java.io.Serializable;
 import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
@@ -43,7 +42,7 @@
     void decodeTest(Version version, List<io.v.v23.vom.testdata.types.TestCase> tests) throws Exception {
         for (io.v.v23.vom.testdata.types.TestCase test : tests) {
           byte[] bytes = TestUtil.hexStringToBytes(test.getHex());
-          Serializable targetVal = test.getValue();
+          Object targetVal = test.getValue();
           if (test.getValue().getElem() != null) {
             targetVal = test.getValue().getElem();
           }
@@ -86,7 +85,7 @@
     }
 
     public void testDecodeVException() throws Exception {
-        Serializable[] params = {
+        Object[] params = {
                 1,
                 "2",
                 ImmutableList.<String>of("3"),
@@ -110,7 +109,7 @@
     }
 
     public void testDecodeVExceptionBadParams() throws Exception {
-        Serializable[] params = {
+        Object[] params = {
                 ImmutableList.<String>of("3"),
                 ImmutableMap.<String, String>of("4", "")
         };
@@ -131,7 +130,7 @@
     }
 
     public void testDecodeEncodeVException() throws Exception {
-        Serializable[] params = {
+        Object[] params = {
                 1,
                 "2",
                 ImmutableList.<String>of("3"),
@@ -179,7 +178,7 @@
         }
 
         SubVException() {
-            super(ID_ACTION, "en", "test", "test", new Serializable[]{ 5 },
+            super(ID_ACTION, "en", "test", "test", new Object[]{ 5 },
                     new Type[]{ Integer.class });
         }
     }