Title: [2207] branches/v-1.4.x: Merge new SunLimitedUnsafeReflectionProvider from trunk into branch (XSTR-751).

Diff

Property changes: branches/v-1.4.x


Modified: svn:mergeinfo

+ /trunk:2151-2152,2154-2156,2158-2163,2165,2172,2175,2177,2188-2189,2197,2199-2201,2204,2206

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java (2206 => 2207)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2011, 2013 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -11,134 +11,32 @@
  */
 package com.thoughtworks.xstream.converters.reflection;
 
-import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
-import java.util.Map;
-import java.util.WeakHashMap;
-
 /**
- * Instantiates a new object on the Sun JVM by bypassing the constructor (meaning code in the constructor
- * will never be executed and parameters do not have to be known). This is the same method used by the internals of
- * standard Java serialization, but relies on internal Sun code that may not be present on all JVMs.
- *
+ * Instantiates a new object on the Sun JVM by bypassing the constructor (meaning code in the constructor will never be
+ * executed and parameters do not have to be known). This is the same method used by the internals of standard Java
+ * serialization, but relies on internal Sun code that may not be present on all JVMs.
+ * 
  * @author Joe Walnes
  * @author Brian Slesinsky
+ * @deprecated As of upcoming use {@link SunUnsafeReflectionProvider}
  */
-public class Sun14ReflectionProvider extends PureJavaReflectionProvider {
-
-    private final static Unsafe unsafe;
-    private final static Exception exception;
-    // references to the Field key are kept in the FieldDictionary
-    private transient Map fieldOffsetCache;
-    static {
-        Unsafe u = null;
-        Exception ex = null;
-        try {
-            Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
-            unsafeField.setAccessible(true);
-            u = (Unsafe) unsafeField.get(null);
-        } catch (SecurityException e) {
-            ex = e;
-        } catch (NoSuchFieldException e) {
-            ex = e;
-        } catch (IllegalArgumentException e) {
-            ex = e;
-        } catch (IllegalAccessException e) {
-            ex = e;
-        }
-        exception = ex;
-        unsafe = u;
-    }
-
+public class Sun14ReflectionProvider extends SunUnsafeReflectionProvider {
+    /**
+     * @deprecated As of upcoming use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider()}
+     */
     public Sun14ReflectionProvider() {
         super();
     }
 
+    /**
+     * @deprecated As of upcoming use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider(FieldDictionary)}
+     */
     public Sun14ReflectionProvider(FieldDictionary dic) {
         super(dic);
     }
-
-    public Object newInstance(Class type) {
-        if (exception != null) {
-            throw new ObjectAccessException("Cannot construct " + type.getName(), exception);
-        }
-        try {
-            return unsafe.allocateInstance(type);
-        } catch (SecurityException e) {
-            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
-        } catch (InstantiationException e) {
-            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
-        } catch (IllegalArgumentException e) {
-            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
-        }
-    }
-
-    public void writeField(Object object, String fieldName, Object value, Class definedIn) {
-        write(fieldDictionary.field(object.getClass(), fieldName, definedIn), object, value);
-    }
-
-    private void write(Field field, Object object, Object value) {
-        if (exception != null) {
-            throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), exception);
-        }
-        try {
-            long offset = getFieldOffset(field);
-            Class type = field.getType();
-            if (type.isPrimitive()) {
-                if (type.equals(Integer.TYPE)) {
-                    unsafe.putInt(object, offset, ((Integer) value).intValue());
-                } else if (type.equals(Long.TYPE)) {
-                    unsafe.putLong(object, offset, ((Long) value).longValue());
-                } else if (type.equals(Short.TYPE)) {
-                    unsafe.putShort(object, offset, ((Short) value).shortValue());
-                } else if (type.equals(Character.TYPE)) {
-                    unsafe.putChar(object, offset, ((Character) value).charValue());
-                } else if (type.equals(Byte.TYPE)) {
-                    unsafe.putByte(object, offset, ((Byte) value).byteValue());
-                } else if (type.equals(Float.TYPE)) {
-                    unsafe.putFloat(object, offset, ((Float) value).floatValue());
-                } else if (type.equals(Double.TYPE)) {
-                    unsafe.putDouble(object, offset, ((Double) value).doubleValue());
-                } else if (type.equals(Boolean.TYPE)) {
-                    unsafe.putBoolean(object, offset, ((Boolean) value).booleanValue());
-                } else {
-                    throw new ObjectAccessException("Could not set field " +
-                            object.getClass() + "." + field.getName() +
-                            ": Unknown type " + type);
-                }
-            } else {
-                unsafe.putObject(object, offset, value);
-            }
-
-        } catch (IllegalArgumentException e) {
-            throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
-        }
-    }
     
-    private synchronized long  getFieldOffset(Field f)
-    {
-        Long l = (Long)fieldOffsetCache.get(f);
-        if (l == null)
-        {
-            l = new Long(unsafe.objectFieldOffset(f));
-            fieldOffsetCache.put(f, l);
-        }
-        
-        return l.longValue();
-    }
-
-    protected void validateFieldAccess(Field field) {
-        // (overriden) don't mind final fields.
-    }
-
     private Object readResolve() {
         init();
         return this;
     }
-
-    protected void init() {
-        super.init();
-        fieldOffsetCache = new WeakHashMap();
-    }
 }

Copied: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java (from rev 2206, trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java) (0 => 2207)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java	                        (rev 0)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004, 2005 Joe Walnes.
+ * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers.
+ * All rights reserved.
+ *
+ * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProvider
+ */
+package com.thoughtworks.xstream.converters.reflection;
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+
+/**
+ * Instantiates a new object bypassing the constructor using undocumented internal JDK features.
+ * <p>
+ * The code in the constructor will never be executed and parameters do not have to be known. This is the same method
+ * used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be
+ * present on all JVMs.
+ * <p>
+ * <p>
+ * The implementation will use standard Java functionality to write any fields. This requires Java 5 as minimum runtime
+ * and is used as fallback on platforms that do not provide the complete implementation level for the internals (like
+ * Dalvik).
+ * <p>
+ * 
+ * @author J&ouml;rg Schaible
+ * @author Joe Walnes
+ * @author Brian Slesinsky
+ * @since upcoming
+ */
+public class SunLimitedUnsafeReflectionProvider extends PureJavaReflectionProvider {
+
+    protected static final Unsafe unsafe;
+    protected static final Exception exception;
+    static {
+        Unsafe u = null;
+        Exception ex = null;
+        try {
+            Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+            unsafeField.setAccessible(true);
+            u = (Unsafe)unsafeField.get(null);
+        } catch (SecurityException e) {
+            ex = e;
+        } catch (NoSuchFieldException e) {
+            ex = e;
+        } catch (IllegalArgumentException e) {
+            ex = e;
+        } catch (IllegalAccessException e) {
+            ex = e;
+        }
+        exception = ex;
+        unsafe = u;
+    }
+
+    /**
+     * @since upcoming
+     */
+    public SunLimitedUnsafeReflectionProvider() {
+        super();
+    }
+
+    /**
+     * @since upcoming
+     */
+    public SunLimitedUnsafeReflectionProvider(FieldDictionary fieldDictionary) {
+        super(fieldDictionary);
+    }
+
+    public Object newInstance(Class type) {
+        if (exception != null) {
+            throw new ObjectAccessException("Cannot construct " + type.getName(), exception);
+        }
+        try {
+            return unsafe.allocateInstance(type);
+        } catch (SecurityException e) {
+            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
+        } catch (InstantiationException e) {
+            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
+        } catch (IllegalArgumentException e) {
+            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
+        }
+    }
+
+    protected void validateFieldAccess(Field field) {
+        // (overriden) don't mind final fields.
+    }
+
+    private Object readResolve() {
+        init();
+        return this;
+    }
+}

Copied: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java (from rev 2206, trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java) (0 => 2207)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java	                        (rev 0)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2004, 2005 Joe Walnes.
+ * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers.
+ * All rights reserved.
+ *
+ * The software in this package is published under the terms of the BSD
+ * style license a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ * 
+ * Created on 08. January 2014 by Joerg Schaible, renamed from Sun14ReflectionProvider
+ */
+package com.thoughtworks.xstream.converters.reflection;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+
+/**
+ * Instantiates a new object bypassing the constructor using undocumented internal JDK features.
+ * <p>
+ * The code in the constructor will never be executed and parameters do not have to be known. This is the same method
+ * used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be
+ * present on all JVMs.
+ * <p>
+ * <p>
+ * The implementation will use the same internals to write into fields. This is a lot faster and was additionally the
+ * only possibility to set final fields prior to Java 5.
+ * <p>
+ * 
+ * @author Joe Walnes
+ * @author Brian Slesinsky
+ * @author J&ouml;rg Schaible
+ * @since upcoming
+ */
+public class SunUnsafeReflectionProvider extends SunLimitedUnsafeReflectionProvider {
+
+    // references to the Field key are kept in the FieldDictionary
+    private transient Map fieldOffsetCache;
+
+    /**
+     * @since upcoming
+     */
+    public SunUnsafeReflectionProvider() {
+        super();
+    }
+
+    /**
+     * @since upcoming
+     */
+    public SunUnsafeReflectionProvider(FieldDictionary dic) {
+        super(dic);
+    }
+
+    public void writeField(Object object, String fieldName, Object value, Class definedIn) {
+        write(fieldDictionary.field(object.getClass(), fieldName, definedIn), object, value);
+    }
+
+    private void write(Field field, Object object, Object value) {
+        if (exception != null) {
+            throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(),
+                exception);
+        }
+        try {
+            long offset = getFieldOffset(field);
+            Class type = field.getType();
+            if (type.isPrimitive()) {
+                if (type.equals(Integer.TYPE)) {
+                    unsafe.putInt(object, offset, ((Integer)value).intValue());
+                } else if (type.equals(Long.TYPE)) {
+                    unsafe.putLong(object, offset, ((Long)value).longValue());
+                } else if (type.equals(Short.TYPE)) {
+                    unsafe.putShort(object, offset, ((Short)value).shortValue());
+                } else if (type.equals(Character.TYPE)) {
+                    unsafe.putChar(object, offset, ((Character)value).charValue());
+                } else if (type.equals(Byte.TYPE)) {
+                    unsafe.putByte(object, offset, ((Byte)value).byteValue());
+                } else if (type.equals(Float.TYPE)) {
+                    unsafe.putFloat(object, offset, ((Float)value).floatValue());
+                } else if (type.equals(Double.TYPE)) {
+                    unsafe.putDouble(object, offset, ((Double)value).doubleValue());
+                } else if (type.equals(Boolean.TYPE)) {
+                    unsafe.putBoolean(object, offset, ((Boolean)value).booleanValue());
+                } else {
+                    throw new ObjectAccessException("Could not set field "
+                        + object.getClass()
+                        + "."
+                        + field.getName()
+                        + ": Unknown type "
+                        + type);
+                }
+            } else {
+                unsafe.putObject(object, offset, value);
+            }
+
+        } catch (IllegalArgumentException e) {
+            throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
+        }
+    }
+
+    private synchronized long getFieldOffset(Field f) {
+        Long l = (Long)fieldOffsetCache.get(f);
+        if (l == null) {
+            l = new Long(unsafe.objectFieldOffset(f));
+            fieldOffsetCache.put(f, l);
+        }
+
+        return l.longValue();
+    }
+
+    private Object readResolve() {
+        init();
+        return this;
+    }
+
+    protected void init() {
+        super.init();
+        fieldOffsetCache = new WeakHashMap();
+    }
+}

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/core/JVM.java (2206 => 2207)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/core/JVM.java	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/core/JVM.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2004, 2005, 2006 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -41,6 +41,7 @@
     private static final boolean isSwingAvailable;
     private static final boolean isSQLAvailable;
     private static final boolean canAllocateWithUnsafe;
+    private static final boolean canWriteWithUnsafe;
     private static final boolean optimizedTreeSetAddAll;
     private static final boolean optimizedTreeMapPutAll;
     private static final boolean canParseUTCDateFormat;
@@ -52,28 +53,72 @@
     private static final boolean reverseFieldOrder = false;
     private static final Class reflectionProviderType;
 
-    static class Broken {
-        Broken() {
+    static class Test {
+        private Object o;
+        private char c;
+        private byte b;
+        private short s;
+        private int i;
+        private long l;
+        private float f;
+        private double d;
+        private boolean bool;
+        Test() {
            throw new UnsupportedOperationException(); 
         }
     }
-    
+
     static {
         boolean test = true;
+        Object unsafe = null;
         try {
             Class unsafeClass = Class.forName("sun.misc.Unsafe");
             Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
             unsafeField.setAccessible(true);
-            Object unsafe = unsafeField.get(null);
+            unsafe = unsafeField.get(null);
             Method allocateInstance = unsafeClass.getDeclaredMethod("allocateInstance", new Class[]{Class.class});
             allocateInstance.setAccessible(true);
-            test = allocateInstance.invoke(unsafe, new Object[]{Broken.class}) != null;
+            test = allocateInstance.invoke(unsafe, new Object[]{Test.class}) != null;
         } catch (Exception e) {
             test = false;
         } catch (Error e) {
             test = false;
         }
         canAllocateWithUnsafe = test;
+        test = false;
+        Class type = PureJavaReflectionProvider.class;
+        if (canUseSunUnsafeReflectionProvider()) {
+            Class cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider");
+            if (cls != null) {
+                try {
+                    ReflectionProvider provider = (ReflectionProvider)DependencyInjectionFactory.newInstance(cls, null);
+                    Test t = (Test)provider.newInstance(Test.class);
+                    try {
+                        provider.writeField(t, "o", "object", Test.class);
+                        provider.writeField(t, "c", new Character('c'), Test.class);
+                        provider.writeField(t, "b", new Byte((byte)1), Test.class);
+                        provider.writeField(t, "s", new Short((short)1), Test.class);
+                        provider.writeField(t, "i", new Integer(1), Test.class);
+                        provider.writeField(t, "l", new Long(1), Test.class);
+                        provider.writeField(t, "f", new Float(1), Test.class);
+                        provider.writeField(t, "d", new Double(1), Test.class);
+                        provider.writeField(t, "bool", Boolean.TRUE, Test.class);
+                        test = true;
+                    } catch(IncompatibleClassChangeError e) {
+                        cls = null;
+                    } catch (ObjectAccessException e) {
+                        cls = null;
+                    }
+                    if (cls == null) {
+                        cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider");
+                    }
+                    type = cls;
+                } catch (ObjectAccessException e) {
+                }
+            }
+        }
+        reflectionProviderType = type;
+        canWriteWithUnsafe = test;
         Comparator comparator = new Comparator() {
             public int compare(Object o1, Object o2) {
                 throw new RuntimeException();
@@ -117,20 +162,6 @@
         isAWTAvailable = loadClassForName("java.awt.Color", false) != null;
         isSwingAvailable = loadClassForName("javax.swing.LookAndFeel", false) != null;
         isSQLAvailable = loadClassForName("java.sql.Date") != null;
-        
-        Class type = PureJavaReflectionProvider.class;
-        if (canUseSun14ReflectionProvider()) {
-            Class cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider");
-            if (cls != null) {
-                try {
-                    ReflectionProvider provider = (ReflectionProvider)DependencyInjectionFactory.newInstance(cls, null);
-                    provider.newInstance(JVM.class);
-                    type = cls;
-                } catch (ObjectAccessException e) {
-                }
-            }
-        }
-        reflectionProviderType = type;
     }
     
     /**
@@ -322,33 +353,19 @@
      */
     public synchronized ReflectionProvider bestReflectionProvider() {
         if (reflectionProvider == null) {
-            try {
-                String className = null;
-                if (canUseSun14ReflectionProvider()) {
-                    className = "com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider";
-                }
-                if (className != null) {
-                    Class cls = loadClassForName(className);
-                    if (cls != null) {
-                        reflectionProvider = (ReflectionProvider) cls.newInstance();
-                    }
-                }
-            } catch (InstantiationException e) {
-            } catch (IllegalAccessException e) {
-            } catch (AccessControlException e) {
-                // thrown when trying to access sun.misc package in Applet context
-            }
-            if (reflectionProvider == null) {
-                reflectionProvider = new PureJavaReflectionProvider();
-            }
+            reflectionProvider = newReflectionProvider();
         }
         return reflectionProvider;
     }
 
-    private static boolean canUseSun14ReflectionProvider() {
+    private static boolean canUseSunUnsafeReflectionProvider() {
         return canAllocateWithUnsafe && is14();
     }
 
+    private static boolean canUseSunLimitedUnsafeReflectionProvider() {
+        return canWriteWithUnsafe;
+    }
+
     /**
      * @deprecated As of 1.4.5
      */
@@ -440,27 +457,21 @@
     }
     
     public static void main(String[] args) {
-        boolean reverse = false;
+        boolean reverseJDK = false;
         Field[] fields = AttributedString.class.getDeclaredFields();
         for (int i = 0; i < fields.length; i++) {
             if (fields[i].getName().equals("text")) {
-                reverse = i > 3;
+                reverseJDK = i > 3;
                 break;
             }
         }
-        class Test {
-            String first;
-            String second;
-            String third;
-            String fourth;
-        }
-        if (reverse) {
-            fields = Test.class.getDeclaredFields();
-            for (int i = 0; i < fields.length; i++) {
-                if (fields[i].getName().equals("first")) {
-                    reverse = i > 3;
-                    break;
-                }
+
+        boolean reverseLocal = false;
+        fields = Test.class.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            if (fields[i].getName().equals("o")) {
+                reverseLocal = i > 3;
+                break;
             }
         }
 
@@ -488,7 +499,8 @@
         System.out.println("java.vendor: " + System.getProperty("java.vendor"));
         System.out.println("java.vm.name: " + System.getProperty("java.vm.name"));
         System.out.println("Version: " + majorJavaVersion);
-        System.out.println("XStream support for enhanced Mode: " + canUseSun14ReflectionProvider());
+        System.out.println("XStream support for enhanced Mode: " + canUseSunUnsafeReflectionProvider());
+        System.out.println("XStream support for reduced Mode: " + canUseSunLimitedUnsafeReflectionProvider());
         System.out.println("Supports AWT: " + isAWTAvailable());
         System.out.println("Supports Swing: " + isSwingAvailable());
         System.out.println("Supports SQL: " + isSQLAvailable());
@@ -498,6 +510,7 @@
         System.out.println("Optimized TreeMap.putAll: " + hasOptimizedTreeMapPutAll());
         System.out.println("Can parse UTC date format: " + canParseUTCDateFormat());
         System.out.println("Can create derive ObjectOutputStream: " + canCreateDerivedObjectOutputStream());
-        System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + reverse);
+        System.out.println("Reverse field order detected for JDK: " + reverseJDK);
+        System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + reverseLocal);
     }
 }

Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java (2206 => 2207)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 XStream Committers.
+ * Copyright (C) 2011, 2013, 2014 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -25,7 +25,7 @@
 import com.thoughtworks.xstream.converters.collections.ArrayConverter;
 import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
-import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
+import com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider;
 import com.thoughtworks.xstream.core.ClassLoaderReference;
 import com.thoughtworks.xstream.core.DefaultConverterLookup;
 import com.thoughtworks.xstream.core.TreeMarshaller;
@@ -35,7 +35,6 @@
 import com.thoughtworks.xstream.io.xml.CompactWriter;
 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
 import com.thoughtworks.xstream.io.xml.XppDriver;
-import com.thoughtworks.xstream.io.xml.XppReader;
 import com.thoughtworks.xstream.mapper.ArrayMapper;
 import com.thoughtworks.xstream.mapper.ClassAliasingMapper;
 import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper;
@@ -66,7 +65,7 @@
         classAliasingMapper.addClassAlias("open-source", OpenSourceSoftware.class);
         mapper = new DefaultImplementationsMapper(new ArrayMapper(classAliasingMapper));
 
-        reflectionProvider = new Sun14ReflectionProvider();
+        reflectionProvider = new SunUnsafeReflectionProvider();
         driver = new XppDriver();
 
         converterLookup = new DefaultConverterLookup();

Deleted: branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProviderTest.java (2206 => 2207)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProviderTest.java	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProviderTest.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2004 Joe Walnes.
- * Copyright (C) 2006, 2007, 2013 XStream Committers.
- * All rights reserved.
- *
- * The software in this package is published under the terms of the BSD
- * style license a copy of which has been included with this distribution in
- * the LICENSE.txt file.
- * 
- * Created on 08. March 2004 by Joe Walnes
- */
-package com.thoughtworks.xstream.converters.reflection;
-
-public class Sun14ReflectionProviderTest extends AbstractReflectionProviderTest {
-
-    // inherits tests from superclass
-
-    public ReflectionProvider createReflectionProvider() {
-        return new Sun14ReflectionProvider();
-    }
-
-    public void testCanWriteFinalFields() {
-        WithFinalFields thingy = new WithFinalFields();
-        reflectionProvider.writeField(thingy, "finalField", "zero", WithFinalFields.class);
-        assertEquals("zero", thingy.finalField);
-
-        reflectionProvider.writeField(thingy, "finalInt", new Integer(1), WithFinalFields.class);
-        assertEquals(1, thingy.finalInt);
-
-        reflectionProvider.writeField(thingy, "finalLong", new Long(2), WithFinalFields.class);
-        assertEquals(2, thingy.finalLong);
-
-        reflectionProvider.writeField(thingy, "finalShort", new Short((short) 3), WithFinalFields.class);
-        assertEquals(3, thingy.finalShort);
-
-        reflectionProvider.writeField(thingy, "finalChar", new Character('4'), WithFinalFields.class);
-        assertEquals('4', thingy.finalChar);
-
-        reflectionProvider.writeField(thingy, "finalByte", new Byte((byte) 5), WithFinalFields.class);
-        assertEquals(5, thingy.finalByte);
-
-        reflectionProvider.writeField(thingy, "finalFloat", new Float(0.6), WithFinalFields.class);
-        assertEquals(0.6f, thingy.finalFloat, 0.0);
-
-        reflectionProvider.writeField(thingy, "finalDouble", new Double(0.7), WithFinalFields.class);
-        assertEquals(0.7, thingy.finalDouble, 0.0);
-
-        reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(true), WithFinalFields.class);
-        assertEquals(true, thingy.finalBoolean);
-
-        reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(false), null);
-        assertEquals(false, thingy.finalBoolean);
-    }
-
-    private static class WithFinalFields {
-        final String finalField;
-        final int finalInt;
-        final long finalLong;
-        final short finalShort;
-        final char finalChar;
-        final byte finalByte;
-        final float finalFloat;
-        final double finalDouble;
-        final boolean finalBoolean;
-
-        private WithFinalFields() {
-            finalField = null;
-            finalChar = '\0';
-            finalInt = 0;
-            finalLong = 0;
-            finalShort = 0;
-            finalByte = 0;
-            finalFloat = 0.0f;
-            finalDouble = 0.0;
-            finalBoolean = false;
-        }
-
-    }
-
-    public void testCanInstantiateWithoutInitializer() {
-        assertCanCreate(Unistantiatable.class);
-    }
-    
-    static class Unistantiatable {
-        {
-            if (true) {
-                throw new IllegalStateException("<init>");
-            }
-        }
-        
-        public Unistantiatable() {
-            throw new IllegalStateException("ctor");
-        }
-        
-        public Unistantiatable(String s) {
-            throw new IllegalStateException("ctor(String)");
-        }
-    }
-}
\ No newline at end of file

Copied: branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java (from rev 2206, trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java) (0 => 2207)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java	                        (rev 0)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2004 Joe Walnes.
+ * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers.
+ * All rights reserved.
+ *
+ * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProviderTest
+ */
+package com.thoughtworks.xstream.converters.reflection;
+
+public class SunLimitedUnsafeReflectionProviderTest extends AbstractReflectionProviderTest {
+
+    // inherits tests from superclass
+
+    public ReflectionProvider createReflectionProvider() {
+        return new SunLimitedUnsafeReflectionProvider();
+    }
+
+    protected static class WithFinalFields {
+        final String finalField;
+        final int finalInt;
+        final long finalLong;
+        final short finalShort;
+        final char finalChar;
+        final byte finalByte;
+        final float finalFloat;
+        final double finalDouble;
+        final boolean finalBoolean;
+
+        private WithFinalFields() {
+            finalField = null;
+            finalChar = '\0';
+            finalInt = 0;
+            finalLong = 0;
+            finalShort = 0;
+            finalByte = 0;
+            finalFloat = 0.0f;
+            finalDouble = 0.0;
+            finalBoolean = false;
+        }
+
+    }
+
+    public void testCanWriteFinalFields() {
+        WithFinalFields thingy = new WithFinalFields();
+        reflectionProvider.writeField(thingy, "finalField", "zero", WithFinalFields.class);
+        assertEquals("zero", thingy.finalField);
+
+        reflectionProvider.writeField(thingy, "finalInt", new Integer(1), WithFinalFields.class);
+        assertEquals(1, thingy.finalInt);
+
+        reflectionProvider.writeField(thingy, "finalLong", new Long(2), WithFinalFields.class);
+        assertEquals(2, thingy.finalLong);
+
+        reflectionProvider.writeField(thingy, "finalShort", new Short((short)3), WithFinalFields.class);
+        assertEquals(3, thingy.finalShort);
+
+        reflectionProvider.writeField(thingy, "finalChar", new Character('4'), WithFinalFields.class);
+        assertEquals('4', thingy.finalChar);
+
+        reflectionProvider.writeField(thingy, "finalByte", new Byte((byte)5), WithFinalFields.class);
+        assertEquals(5, thingy.finalByte);
+
+        reflectionProvider.writeField(thingy, "finalFloat", new Float(0.6), WithFinalFields.class);
+        assertEquals(0.6f, thingy.finalFloat, 0.0);
+
+        reflectionProvider.writeField(thingy, "finalDouble", new Double(0.7), WithFinalFields.class);
+        assertEquals(0.7, thingy.finalDouble, 0.0);
+
+        reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(true), WithFinalFields.class);
+        assertEquals(true, thingy.finalBoolean);
+
+        reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(false), null);
+        assertEquals(false, thingy.finalBoolean);
+    }
+
+    protected static class Unistantiatable {
+        {
+            if (true) {
+                throw new IllegalStateException("<init>");
+            }
+        }
+
+        public Unistantiatable() {
+            throw new IllegalStateException("ctor");
+        }
+
+        public Unistantiatable(String s) {
+            throw new IllegalStateException("ctor(String)");
+        }
+    }
+
+    public void testCanInstantiateWithoutInitializer() {
+        assertCanCreate(Unistantiatable.class);
+    }
+}

Copied: branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java (from rev 2206, trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java) (0 => 2207)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java	                        (rev 0)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java	2014-01-08 16:42:54 UTC (rev 2207)
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2004 Joe Walnes.
+ * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers.
+ * All rights reserved.
+ *
+ * The software in this package is published under the terms of the BSD
+ * style license a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ * 
+ * Created on 08. January 2014 by Joerg Schaible, renamed from Sun14RelfectrionProviderTest.
+ */
+package com.thoughtworks.xstream.converters.reflection;
+
+public class SunUnsafeReflectionProviderTest extends SunLimitedUnsafeReflectionProviderTest {
+
+    // inherits tests from superclass
+
+    public ReflectionProvider createReflectionProvider() {
+        return new SunUnsafeReflectionProvider();
+    }
+}
\ No newline at end of file

Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2206 => 2207)


--- branches/v-1.4.x/xstream-distribution/src/content/changes.html	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,7 +1,7 @@
 <html>
 <!--
  Copyright (C) 2005, 2006 Joe Walnes.
- Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream committers.
+ Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 XStream committers.
  All rights reserved.
  
  The software in this package is published under the terms of the BSD
@@ -36,6 +36,8 @@
     
     <ul>
    		<li>java.bean.EventHandler no longer handled automatically because of severe security vulnerability.</li>
+    	<li>JIRA:XSTR-751: New SunLimitedUnsafeReflectionProvider that uses undocumented features only to allocate new
+    	instances as required on Dalvik.</li>
    		<li>Fix instantiation of AnnotationMapper that requires ConverterLookup and ConverterRegistry to be the same
    		instance.</li>
     </ul>
@@ -52,6 +54,9 @@
     <h2>API changes</h2>
 
     <ul>
+    	<li>Added c.t.x.converters.reflection.SunLimitedUnsafeReflectionProvider.</li>
+    	<li>Deprecated c.t.x.converters.reflection.Sun14ReflectionProvider in favor of new
+    	c.t.x.converters.reflection.SunUnsafeReflectionProvider.</li>
     	<li>Added c.t.x.converters.reflection.ReflectionConverter(Mapper,ReflectionProvider,Class).</li>
     </ul>
 

Modified: branches/v-1.4.x/xstream-distribution/src/content/faq.html (2206 => 2207)


--- branches/v-1.4.x/xstream-distribution/src/content/faq.html	2014-01-08 16:10:50 UTC (rev 2206)
+++ branches/v-1.4.x/xstream-distribution/src/content/faq.html	2014-01-08 16:42:54 UTC (rev 2207)
@@ -1,7 +1,7 @@
 <html>
 <!--
  Copyright (C) 2005, 2006 Joe Walnes.
- Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream committers.
+ Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 XStream committers.
  All rights reserved.
  
  The software in this package is published under the terms of the BSD
@@ -52,10 +52,12 @@
     <!-- ...................................................... -->
     <h2 id="Compatibility_enhanced_mode_jvm">Which JVMs allow XStream to operate in enhanced mode?</h2>
 
-    <p>XStream will check since version 1.4.5 a working enhanced mode dynamically if it is available based on internal
-    Sun classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP, IBM and Blackdown 1.4 JVMs and
-    onwards, for Hitachi, SAP and Diablo from 1.5 and onwards, for BEA JRockit starting with R25.1.0 and for OpenJDK.
-    Note, that an active SecurityManager might prevent the usage of the enhanced mode also.</p>
+    <p>XStream will check since version 1.4.5 a working enhanced mode dynamically if it is available based on
+    undocumented internal Java runtime classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP,
+    IBM and Blackdown 1.4 JVMs and onwards, for IcedTea 6 and onwards, for Hitachi, SAP and Diablo from 1.5 and
+    onwards, for BEA JRockit starting with R25.1.0. Generally it works for all modern Java runtimes based on OpenJDK.
+    Android basically supports the enhanced mode, but its security model limits the types that can be handled. Note,
+    that an active SecurityManager might prevent the usage of the enhanced mode also.</p>
 
     <!-- ...................................................... -->
     <h2 id="Compatibility_enhanced_mode_advantage">What are the advantages of using enhanced mode over pure Java mode?</h2>
@@ -88,7 +90,7 @@
     <h2 id="Compatibility_Android">Can I use XStream in an Android application?</h2>
 
 	<p>XStream does work in Android 1.0, but is reported to have limited capabilities. Since XStream 1.4 Android is 
-	treated at least as JD 5 platform, but it e.g. does not include the java.beans package. Therefore you cannot use
+	treated at least as JDK 5 platform, but it e.g. does not include the java.beans package. Therefore you cannot use
 	the JavaBeanConverter. Note, that Android provides an XML Pull Parser, therefore XStream can work without
 	additional dependencies.</p>
 

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to