avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cutt...@apache.org
Subject svn commit: r1607711 - in /avro/trunk: ./ lang/java/avro/src/main/java/org/apache/avro/reflect/ lang/java/avro/src/test/java/org/apache/avro/reflect/
Date Thu, 03 Jul 2014 18:35:42 GMT
Author: cutting
Date: Thu Jul  3 18:35:42 2014
New Revision: 1607711

URL: http://svn.apache.org/r1607711
Log:
AVRO-1498. Java: Fix custom encodings to work in reflect without Unsafe access.  Contributed
by Christopher Mann.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/FieldAccessReflect.java
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java
    avro/trunk/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1607711&r1=1607710&r2=1607711&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Thu Jul  3 18:35:42 2014
@@ -110,6 +110,9 @@ Trunk (not yet released)
     AVRO-1499. Ruby: Fix encoding issue that caused corrupted data files
     to be written under Ruby 2.0+. (Willem van Bergen and martinkl)
 
+    AVRO-1498. Java: Fix custom encodings to work in reflect without
+    Unsafe access. (Christopher Mann via cutting)
+
 Avro 1.7.6 (15 January 2014)
 
   NEW FEATURES

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/FieldAccessReflect.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/FieldAccessReflect.java?rev=1607711&r1=1607710&r2=1607711&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/FieldAccessReflect.java
(original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/FieldAccessReflect.java
Thu Jul  3 18:35:42 2014
@@ -17,6 +17,10 @@
  */
 package org.apache.avro.reflect;
 
+import org.apache.avro.AvroRuntimeException;
+import org.apache.avro.io.Decoder;
+import org.apache.avro.io.Encoder;
+
 import java.io.IOException;
 import java.lang.reflect.Field;
 
@@ -24,11 +28,18 @@ class FieldAccessReflect extends FieldAc
 
   @Override
   protected FieldAccessor getAccessor(Field field) {
+    AvroEncode enc = field.getAnnotation(AvroEncode.class);
+    if (enc != null)
+      try {
+        return new ReflectionBasesAccessorCustomEncoded(field, enc.using().newInstance());
+      } catch (Exception e) {
+        throw new AvroRuntimeException("Could not instantiate custom Encoding");
+      }
     return new ReflectionBasedAccessor(field);
   }
 
-  private final class ReflectionBasedAccessor extends FieldAccessor {
-    private final Field field;
+  private class ReflectionBasedAccessor extends FieldAccessor {
+    protected final Field field;
     private boolean isStringable;
     private boolean isCustomEncoded;
 
@@ -69,6 +80,42 @@ class FieldAccessReflect extends FieldAc
     protected boolean isCustomEncoded() {
       return isCustomEncoded;
     }
+  }
+
+  private final class ReflectionBasesAccessorCustomEncoded extends ReflectionBasedAccessor
{
+
+    private CustomEncoding<?> encoding;
+
+    public ReflectionBasesAccessorCustomEncoded(Field f, CustomEncoding<?> encoding)
{
+      super(f);
+      this.encoding = encoding;
+  }
+
+    @Override
+    protected void read(Object object, Decoder in) throws IOException {
+      try {
+        field.set(object, encoding.read(in));
+      } catch (IllegalAccessException e) {
+        throw new AvroRuntimeException(e);
+}
+    }
 
+    @Override
+    protected void write(Object object, Encoder out) throws IOException {
+      try {
+        encoding.write(field.get(object), out);
+      } catch (IllegalAccessException e) {
+        throw new AvroRuntimeException(e);
+      }
+    }
+
+    protected boolean isCustomEncoded() {
+      return true;
+    }
+
+    @Override
+    protected boolean supportsIO() {
+      return true;
+    }
   }
 }

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java?rev=1607711&r1=1607710&r2=1607711&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java Thu Jul
 3 18:35:42 2014
@@ -206,7 +206,7 @@ public class ReflectData extends Specifi
     }
   }
   
-  private static final ConcurrentHashMap<Class<?>, ClassAccessorData> 
+  static final ConcurrentHashMap<Class<?>, ClassAccessorData> 
     ACCESSOR_CACHE = new ConcurrentHashMap<Class<?>, ClassAccessorData>();
 
   private static class ClassAccessorData {

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java?rev=1607711&r1=1607710&r2=1607711&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java Thu
Jul  3 18:35:42 2014
@@ -33,8 +33,11 @@ class ReflectionUtil {
   private ReflectionUtil() {
   }
 
-  private static final FieldAccess FIELD_ACCESS;
+  private static FieldAccess fieldAccess;
   static {
+    resetFieldAccess();
+  }
+  static void resetFieldAccess() {
     // load only one implementation of FieldAccess
     // so it is monomorphic and the JIT can inline
     FieldAccess access = null;
@@ -60,7 +63,7 @@ class ReflectionUtil {
             "Unable to load a functional FieldAccess class!");
       }
     }
-    FIELD_ACCESS = access;
+    fieldAccess = access;
   }
 
   private static <T> T load(String name, Class<T> type) throws Exception {
@@ -69,7 +72,7 @@ class ReflectionUtil {
   }
 
   public static FieldAccess getFieldAccess() {
-    return FIELD_ACCESS;
+    return fieldAccess;
   }
 
   private static boolean validate(FieldAccess access) throws Exception {

Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java?rev=1607711&r1=1607710&r2=1607711&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java Thu Jul
 3 18:35:42 2014
@@ -719,6 +719,24 @@ public class TestReflect {
     assertEquals(b, decoded);
   }
 
+  @Test public void testDisableUnsafe() throws Exception {
+    String saved = System.getProperty("avro.disable.unsafe");
+    try {
+      System.setProperty("avro.disable.unsafe", "true");
+      ReflectData.ACCESSOR_CACHE.clear();
+      ReflectionUtil.resetFieldAccess();
+      testMultipleAnnotations();
+      testRecordWithNullIO();
+    } finally {
+      if (saved == null)
+        System.clearProperty("avro.disable.unsafe");
+      else
+        System.setProperty("avro.disable.unsafe", saved);
+      ReflectData.ACCESSOR_CACHE.clear();
+      ReflectionUtil.resetFieldAccess();
+    }
+  }
+
   public static class SampleRecord {
     public int x = 1;
     private int y = 2;



Mime
View raw message