You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by dk...@apache.org on 2018/11/06 20:39:26 UTC

[avro] branch master updated: Remove use of guava by utilizing java8 lambdas and collections

This is an automated email from the ASF dual-hosted git repository.

dkulp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new c78a3d5  Remove use of guava by utilizing java8 lambdas and collections
c78a3d5 is described below

commit c78a3d5ea4e7e511ba9f6182157956db3e65e1a0
Author: Daniel Kulp <dk...@apache.org>
AuthorDate: Tue Nov 6 15:38:51 2018 -0500

    Remove use of guava by utilizing java8 lambdas and collections
---
 lang/java/avro/pom.xml                             |  42 ++---
 .../java/org/apache/avro/generic/GenericData.java  |  11 +-
 .../apache/avro/message/BinaryMessageDecoder.java  |   4 +-
 .../apache/avro/message/BinaryMessageEncoder.java  |   7 +-
 .../java/org/apache/avro/message/SchemaStore.java  |   4 +-
 .../java/org/apache/avro/reflect/ReflectData.java  |  28 +--
 .../org/apache/avro/specific/SpecificData.java     |  58 +++---
 .../java/org/apache/avro/reflect/TestReflect.java  |   4 +-
 lang/java/compiler/pom.xml                         |  29 ---
 .../apache/avro/compiler/idl/ResolvingVisitor.java |   6 +-
 .../apache/avro/compiler/idl/SchemaResolver.java   |   2 +-
 .../org/apache/avro/compiler/schema/Schemas.java   |  16 +-
 .../java/org/apache/avro/grpc/AvroGrpcClient.java  |  15 +-
 .../java/org/apache/avro/grpc/AvroGrpcServer.java  |   8 +-
 lang/java/guava/pom.xml                            |  92 ---------
 .../main/java/org/apache/avro/GuavaClasses.java    |  39 ----
 .../java/guava/src/main/resources/META-INF/LICENSE | 209 ---------------------
 lang/java/pom.xml                                  |   1 -
 18 files changed, 107 insertions(+), 468 deletions(-)

diff --git a/lang/java/avro/pom.xml b/lang/java/avro/pom.xml
index 999cea1..9d6ee2e 100644
--- a/lang/java/avro/pom.xml
+++ b/lang/java/avro/pom.xml
@@ -37,7 +37,6 @@
   <properties>
     <osgi.import>
       !org.apache.avro*,
-      !com.google.common*,
       com.thoughtworks.paranamer,
       com.fasterxml.jackson*,
       org.xerial.snappy;resolution:=optional,
@@ -86,30 +85,6 @@
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <artifactSet>
-                <includes>
-                  <include>org.apache.avro:avro-guava-dependencies</include>
-                </includes>
-              </artifactSet>
-              <relocations>
-                <relocation>
-                  <pattern>com.google.common</pattern>
-                  <shadedPattern>avro.shaded.com.google.common</shadedPattern>
-                </relocation>
-              </relocations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
 
@@ -166,11 +141,6 @@
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.avro</groupId>
-      <artifactId>avro-guava-dependencies</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-core</artifactId>
     </dependency>
@@ -209,6 +179,18 @@
       <groupId>com.github.luben</groupId>
       <artifactId>zstd-jni</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion> <!-- GPL -->
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
   </dependencies>
 
 </project>
diff --git a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
index 419cdba..ba538d2 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
@@ -24,12 +24,14 @@ import java.nio.charset.StandardCharsets;
 import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 import org.apache.avro.AvroMissingFieldException;
 import org.apache.avro.AvroRuntimeException;
@@ -54,8 +56,6 @@ import org.apache.avro.util.internal.Accessor;
 
 import com.fasterxml.jackson.databind.JsonNode;
 
-import com.google.common.collect.MapMaker;
-
 /** Utilities for generic Java data. See {@link GenericRecordBuilder} for a convenient
  * way to build {@link GenericRecord} instances.
  * @see GenericRecordBuilder
@@ -984,7 +984,7 @@ public class GenericData {
   }
 
   private final Map<Field, Object> defaultValueCache
-    = new MapMaker().weakKeys().makeMap();
+    = Collections.synchronizedMap(new WeakHashMap<>());
 
   /**
    * Gets the default value of the given field, if any.
@@ -992,7 +992,7 @@ public class GenericData {
    * @return the default value associated with the given field,
    * or null if none is specified in the schema.
    */
-  @SuppressWarnings({ "rawtypes", "unchecked" })
+  @SuppressWarnings({ "unchecked" })
   public Object getDefaultValue(Field field) {
     JsonNode json = Accessor.defaultValue(field);
     if (json == null)
@@ -1021,6 +1021,9 @@ public class GenericData {
         defaultValue =
           createDatumReader(field.schema()).read(null, decoder);
 
+        // this MAY result in two threads creating the same defaultValue
+        // and calling put.  The last thread will win.  However,
+        // that's not an issue.
         defaultValueCache.put(field, defaultValue);
       } catch (IOException e) {
         throw new AvroRuntimeException(e);
diff --git a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java
index 7c3a306..9a48646 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java
@@ -19,7 +19,6 @@
 
 package org.apache.avro.message;
 
-import com.google.common.collect.MapMaker;
 import org.apache.avro.Schema;
 import org.apache.avro.SchemaNormalization;
 import org.apache.avro.generic.GenericData;
@@ -28,6 +27,7 @@ import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * A {@link MessageDecoder} that reads a binary-encoded datum. This checks for
@@ -69,7 +69,7 @@ public class BinaryMessageDecoder<D> extends MessageDecoder.BaseDecoder<D> {
   private final SchemaStore resolver;
 
   private final Map<Long, RawMessageDecoder<D>> codecByFingerprint =
-      new MapMaker().makeMap();
+      new ConcurrentHashMap<>();
 
   /**
    * Creates a new {@link BinaryMessageEncoder} that uses the given
diff --git a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageEncoder.java b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageEncoder.java
index e4eb43e..49b7cf8 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageEncoder.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageEncoder.java
@@ -19,7 +19,6 @@
 
 package org.apache.avro.message;
 
-import com.google.common.primitives.Bytes;
 import org.apache.avro.AvroRuntimeException;
 import org.apache.avro.Schema;
 import org.apache.avro.SchemaNormalization;
@@ -113,7 +112,11 @@ public class BinaryMessageEncoder<D> implements MessageEncoder<D> {
       try {
         byte[] fp = SchemaNormalization
             .parsingFingerprint("CRC-64-AVRO", schema);
-        return Bytes.concat(V1_HEADER, fp);
+
+        byte[] ret = new byte[V1_HEADER.length + fp.length];
+        System.arraycopy(V1_HEADER, 0, ret, 0, V1_HEADER.length);
+        System.arraycopy(fp, 0, ret, V1_HEADER.length, fp.length);
+        return ret;
       } catch (NoSuchAlgorithmException e) {
         throw new AvroRuntimeException(e);
       }
diff --git a/lang/java/avro/src/main/java/org/apache/avro/message/SchemaStore.java b/lang/java/avro/src/main/java/org/apache/avro/message/SchemaStore.java
index 6e89b52..15aa2f8 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/message/SchemaStore.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/message/SchemaStore.java
@@ -19,10 +19,10 @@
 
 package org.apache.avro.message;
 
-import com.google.common.collect.MapMaker;
 import org.apache.avro.Schema;
 import org.apache.avro.SchemaNormalization;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Interface for classes that can provide avro schemas by fingerprint.
@@ -42,7 +42,7 @@ public interface SchemaStore {
    * This class is thread-safe.
    */
   class Cache implements SchemaStore {
-    private final Map<Long, Schema> schemas = new MapMaker().makeMap();
+    private final Map<Long, Schema> schemas = new ConcurrentHashMap<>();
 
     /**
      * Adds a schema to this cache that can be retrieved using its AVRO-CRC-64
diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
index d8eb2cb..d26d1f9 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
@@ -36,9 +36,9 @@ import java.util.IdentityHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.common.collect.MapMaker;
 import org.apache.avro.AvroRemoteException;
 import org.apache.avro.AvroRuntimeException;
 import org.apache.avro.AvroTypeException;
@@ -234,14 +234,23 @@ public class ReflectData extends SpecificData {
     }
   }
 
-  static final ConcurrentHashMap<Class<?>, ClassAccessorData>
-    ACCESSOR_CACHE = new ConcurrentHashMap<>();
+  static final ClassValue<ClassAccessorData>
+    ACCESSOR_CACHE = new ClassValue<ClassAccessorData>() {
+      @Override
+      protected ClassAccessorData computeValue(Class<?> c) {
+        if (!IndexedRecord.class.isAssignableFrom(c)){
+          return new ClassAccessorData(c);
+        }
+        return null;
+      }
+  };
 
   static class ClassAccessorData {
     private final Class<?> clazz;
     private final Map<String, FieldAccessor> byName =
         new HashMap<>();
-    final Map<Schema, FieldAccessor[]> bySchema = new MapMaker().weakKeys().makeMap();
+    //getAccessorsFor is already synchronized, no need to wrap
+    final Map<Schema, FieldAccessor[]> bySchema = new WeakHashMap<>();
 
     private ClassAccessorData(Class<?> c) {
       clazz = c;
@@ -262,6 +271,7 @@ public class ReflectData extends SpecificData {
      * index of the given schema.
      */
     private synchronized FieldAccessor[] getAccessorsFor(Schema schema) {
+      //if synchronized is removed from this method, adjust bySchema appropriately
       FieldAccessor[] result = bySchema.get(schema);
       if (result == null) {
         result = createAccessorsFor(schema);
@@ -290,15 +300,7 @@ public class ReflectData extends SpecificData {
   }
 
   private ClassAccessorData getClassAccessorData(Class<?> c) {
-    ClassAccessorData data = ACCESSOR_CACHE.get(c);
-    if(data == null && !IndexedRecord.class.isAssignableFrom(c)){
-      ClassAccessorData newData = new ClassAccessorData(c);
-      data = ACCESSOR_CACHE.putIfAbsent(c, newData);
-      if (null == data) {
-        data = newData;
-      }
-    }
-    return data;
+    return ACCESSOR_CACHE.get(c);
   }
 
   private FieldAccessor[] getFieldAccessors(Class<?> c, Schema s) {
diff --git a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
index 60d43dc..d7b2bf8 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.LinkedHashMap;
 import java.nio.ByteBuffer;
@@ -31,9 +32,6 @@ import java.lang.reflect.ParameterizedType;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
 import org.apache.avro.Schema;
 import org.apache.avro.Protocol;
 import org.apache.avro.AvroRuntimeException;
@@ -55,8 +53,20 @@ public class SpecificData extends GenericData {
 
   private static final Class<?>[] NO_ARG = new Class[]{};
   private static final Class<?>[] SCHEMA_ARG = new Class[]{Schema.class};
-  private static final Map<Class,Constructor> CTOR_CACHE =
-    new ConcurrentHashMap<>();
+  private static final ClassValue<Constructor> CTOR_CACHE = new ClassValue<Constructor>() {
+    @Override
+    protected Constructor computeValue(Class<?> c) {
+      boolean useSchema = SchemaConstructable.class.isAssignableFrom(c);
+      try {
+        Constructor meth = c.getDeclaredConstructor(useSchema ? SCHEMA_ARG : NO_ARG);
+        meth.setAccessible(true);
+        return meth;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+  };
 
   public static final String CLASS_PROP = "java-class";
   public static final String KEY_CLASS_PROP = "java-key-class";
@@ -237,23 +247,34 @@ public class SpecificData extends GenericData {
     return namespace + "$" + name;
   }
 
-  private final LoadingCache<java.lang.reflect.Type,Schema> schemaCache =
-      CacheBuilder.newBuilder()
-          .weakKeys()
-          .build(new CacheLoader<java.lang.reflect.Type,Schema>() {
-            public Schema load(java.lang.reflect.Type type)
-                throws AvroRuntimeException {
-              return createSchema(type, new LinkedHashMap<>());
-            }
-          });
+  // cache for schemas created from Class objects.  Use ClassValue to avoid
+  // locking classloaders and is GC and thread safe.
+  private final ClassValue<Schema> schemaClassCache = new ClassValue<Schema>() {
+    @Override
+    protected Schema computeValue(Class<?> type) {
+      return createSchema(type, new LinkedHashMap<>());
+    }
+  };
+  // for non-class objects, use a WeakHashMap, but this needs a sync block around it
+  private final Map<java.lang.reflect.Type, Schema> schemaTypeCache = new WeakHashMap<>();
 
   /** Find the schema for a Java type. */
   public Schema getSchema(java.lang.reflect.Type type) {
     try {
-      return schemaCache.get(type);
+      if (type instanceof Class) {
+        return schemaClassCache.get((Class<?>)type);
+      }
+      synchronized (schemaTypeCache) {
+        Schema s = schemaTypeCache.get(type);
+        if (s == null) {
+          s = createSchema(type, new LinkedHashMap<>());
+          schemaTypeCache.put(type, s);
+        }
+        return s;
+      }
     } catch (Exception e) {
       throw (e instanceof AvroRuntimeException) ?
-          (AvroRuntimeException)e.getCause() : new AvroRuntimeException(e);
+          (AvroRuntimeException)e : new AvroRuntimeException(e);
     }
   }
 
@@ -371,11 +392,6 @@ public class SpecificData extends GenericData {
     Object result;
     try {
       Constructor meth = (Constructor)CTOR_CACHE.get(c);
-      if (meth == null) {
-        meth = c.getDeclaredConstructor(useSchema ? SCHEMA_ARG : NO_ARG);
-        meth.setAccessible(true);
-        CTOR_CACHE.put(c, meth);
-      }
       result = meth.newInstance(useSchema ? new Object[]{s} : (Object[])null);
     } catch (Exception e) {
       throw new RuntimeException(e);
diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
index 85debac..8304bd0 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
@@ -326,7 +326,7 @@ public class TestReflect {
     r9_1.value = r8;
     checkReadWrite(r9_1, ReflectData.get().getSchema(R9_1.class));
   }
-  
+
   // test union annotation on methods and parameters
   public static interface P0 {
     @Union({Void.class,String.class})
@@ -581,7 +581,7 @@ public class TestReflect {
     check(o.getClass(), schemaJson);
   }
 
-  private void check(Type type, String schemaJson) {
+  private void check(java.lang.reflect.Type type, String schemaJson) {
     assertEquals(schemaJson, ReflectData.get().getSchema(type).toString());
   }
 
diff --git a/lang/java/compiler/pom.xml b/lang/java/compiler/pom.xml
index ec221d4..d236df0 100644
--- a/lang/java/compiler/pom.xml
+++ b/lang/java/compiler/pom.xml
@@ -90,30 +90,6 @@
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <artifactSet>
-                <includes>
-                  <include>org.apache.avro:avro-guava-dependencies</include>
-                </includes>
-              </artifactSet>
-              <relocations>
-                <relocation>
-                  <pattern>com.google.common</pattern>
-                  <shadedPattern>avro.shaded.com.google.common</shadedPattern>
-                </relocation>
-              </relocations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
         <version>1.6.0</version>
@@ -204,11 +180,6 @@
       <groupId>joda-time</groupId>
       <artifactId>joda-time</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.avro</groupId>
-      <artifactId>avro-guava-dependencies</artifactId>
-      <version>${project.version}</version>
-    </dependency>
   </dependencies>
 
 </project>
diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java
index 9ccd7e7..890c0e3 100644
--- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java
+++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java
@@ -17,10 +17,11 @@
  */
 package org.apache.avro.compiler.idl;
 
-import com.google.common.base.Function;
 import java.util.ArrayList;
 import java.util.IdentityHashMap;
 import java.util.List;
+import java.util.function.Function;
+
 import org.apache.avro.AvroTypeException;
 import org.apache.avro.Schema;
 import org.apache.avro.Schema.Field;
@@ -41,7 +42,8 @@ public final class ResolvingVisitor implements SchemaVisitor<Schema> {
   private final Schema root;
 
 
-  public ResolvingVisitor(final Schema root, final IdentityHashMap<Schema, Schema> replace,
+  public ResolvingVisitor(final Schema root,
+          final IdentityHashMap<Schema, Schema> replace,
           final Function<String, Schema> symbolTable) {
     this.replace = replace;
     this.symbolTable = symbolTable;
diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java
index ee87337..21ab3dd 100644
--- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java
+++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java
@@ -17,13 +17,13 @@
  */
 package org.apache.avro.compiler.idl;
 
-import com.google.common.base.Function;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.apache.avro.Protocol;
 import org.apache.avro.Schema;
diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java
index 7d4bd6a..29b9924 100644
--- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java
+++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java
@@ -17,9 +17,6 @@
  */
 package org.apache.avro.compiler.schema;
 
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Lists;
 import java.util.ArrayDeque;
 import java.util.Arrays;
 import java.util.Deque;
@@ -27,6 +24,8 @@ import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 import org.apache.avro.JsonProperties;
 import org.apache.avro.LogicalType;
@@ -141,13 +140,10 @@ public final class Schemas {
               visited.put(schema, schema);
               break;
             case RECORD:
-              terminate = visitNonTerminal(visitor, schema, dq,
-                  Lists.transform(Lists.reverse(schema.getFields()), new Function<Field, Schema>() {
-                    @Override
-                    public Schema apply(Field f) {
-                      return f.schema();
-                    }
-                  }));
+              Iterator<Schema> reverseSchemas = schema.getFields().stream().map(Field::schema)
+                  .collect(Collectors.toCollection(ArrayDeque::new))
+                  .descendingIterator();
+              terminate = visitNonTerminal(visitor, schema, dq, () -> reverseSchemas);
               visited.put(schema, schema);
               break;
             case UNION:
diff --git a/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcClient.java b/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcClient.java
index f0e7d22..e4e03c6 100644
--- a/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcClient.java
+++ b/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcClient.java
@@ -18,8 +18,6 @@
 
 package org.apache.avro.grpc;
 
-import com.google.common.base.Throwables;
-
 import org.apache.avro.AvroRemoteException;
 import org.apache.avro.AvroRuntimeException;
 import org.apache.avro.Protocol;
@@ -91,13 +89,16 @@ public abstract class AvroGrpcClient {
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       try {
         return invokeUnaryMethod(method, args);
+      } catch (RuntimeException re) {
+        //rethrow any runtime exception
+        throw re;
       } catch (Exception e) {
         //throw any of the declared exceptions
         for (Class<?> exceptionClass : method.getExceptionTypes()) {
-          Throwables.propagateIfInstanceOf(e, (Class<Exception>) exceptionClass);
+          if (exceptionClass.isInstance(e)) {
+            throw e;
+          }
         }
-        //also throw if any runtime exception
-        Throwables.propagateIfInstanceOf(e, RuntimeException.class);
         //wrap all other exceptions
         throw new AvroRemoteException(e);
       }
@@ -124,7 +125,9 @@ public abstract class AvroGrpcClient {
       try {
         return callFuture.get();
       } catch (Exception e) {
-        Throwables.propagateIfInstanceOf(e.getCause(), Exception.class);
+        if (e.getCause() instanceof Exception) {
+          throw (Exception)e.getCause();
+        }
         throw new AvroRemoteException(e.getCause());
       }
     }
diff --git a/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcServer.java b/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcServer.java
index c18822e..ff0d187 100644
--- a/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcServer.java
+++ b/lang/java/grpc/src/main/java/org/apache/avro/grpc/AvroGrpcServer.java
@@ -18,8 +18,6 @@
 
 package org.apache.avro.grpc;
 
-import com.google.common.base.Throwables;
-
 import org.apache.avro.Protocol;
 
 import java.lang.reflect.InvocationTargetException;
@@ -113,7 +111,11 @@ public abstract class AvroGrpcServer {
       try {
         getMethod().invoke(getServiceImpl(), request);
       } catch (Exception e) {
-        LOG.log(Level.WARNING, "Error processing one-way rpc", Throwables.getRootCause(e));
+        Throwable cause = e;
+        while (cause.getCause() != null && cause != cause.getCause()) {
+          cause = cause.getCause();
+        }
+        LOG.log(Level.WARNING, "Error processing one-way rpc", cause);
       }
     }
   }
diff --git a/lang/java/guava/pom.xml b/lang/java/guava/pom.xml
deleted file mode 100644
index 4efcfe7..0000000
--- a/lang/java/guava/pom.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<project
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <artifactId>avro-parent</artifactId>
-    <groupId>org.apache.avro</groupId>
-    <version>1.9.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-
-  <artifactId>avro-guava-dependencies</artifactId>
-
-  <name>Apache Avro Guava Dependencies</name>
-  <url>http://avro.apache.org</url>
-  <description>Temporary artifact of guava dependencies</description>
-  <packaging>jar</packaging>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- this module has no public javadoc -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <!-- Include only classes referenced in this module and their
-                   dependencies. To add a Guava class, add it to
-                   org.apache.avro.GuavaClasses. -->
-              <minimizeJar>true</minimizeJar>
-              <artifactSet>
-                <includes>
-                  <include>com.google.guava:guava</include>
-                </includes>
-              </artifactSet>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-      <version>${guava.version}</version>
-      <exclusions>
-        <exclusion> <!-- GPL -->
-          <groupId>com.google.code.findbugs</groupId>
-          <artifactId>jsr305</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>com.github.stephenc.findbugs</groupId>
-      <artifactId>findbugs-annotations</artifactId>
-      <version>${findbugs-annotations.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>
-
diff --git a/lang/java/guava/src/main/java/org/apache/avro/GuavaClasses.java b/lang/java/guava/src/main/java/org/apache/avro/GuavaClasses.java
deleted file mode 100644
index f6b1b93..0000000
--- a/lang/java/guava/src/main/java/org/apache/avro/GuavaClasses.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.avro;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.MapMaker;
-import com.google.common.primitives.Bytes;
-
-class GuavaClasses {
-  /*
-   * Referencing Guava classes here includes them in the minimized Guava jar
-   * that is shaded in the avro jar.
-   */
-  static {
-    MapMaker.class.getName();
-    Bytes.class.getName();
-    LoadingCache.class.getName();
-    CacheBuilder.class.getName();
-    CacheLoader.class.getName();
-  }
-}
diff --git a/lang/java/guava/src/main/resources/META-INF/LICENSE b/lang/java/guava/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index 3d6d84e..0000000
--- a/lang/java/guava/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,209 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-----------------------------------------------------------------------
-License for Guava classes included in this binary artifact:
-
-Copyright: 2006-2015 The Guava Authors
-License: http://www.apache.org/licenses/LICENSE-2.0 (see above)
-
diff --git a/lang/java/pom.xml b/lang/java/pom.xml
index 0e85906..0abf3c0 100644
--- a/lang/java/pom.xml
+++ b/lang/java/pom.xml
@@ -85,7 +85,6 @@
   </properties>
 
   <modules>
-    <module>guava</module>
     <module>avro</module>
     <module>compiler</module>
     <module>maven-plugin</module>