Log Message
No converter should throw an exception at initialization, just because it cannot use reflection or it will not find a declared field or method (XSTR-200, XSTR-566).
Modified Paths
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java
- trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -44,18 +44,7 @@
*/
public class PropertiesConverter implements Converter {
- private final static Field defaultsField;
- static {
- Field field = null;
- try {
- field = Fields.find(Properties.class, "defaults");
- } catch (SecurityException ex) {
- // ignore, no access possible with current SecurityManager
- } catch (RuntimeException ex) {
- throw new ExceptionInInitializerError("No field 'defaults' in type Properties found");
- }
- defaultsField = field;
- }
+ private final static Field defaultsField = Fields.locate(Properties.class, Properties.class, false);
private final boolean sort;
public PropertiesConverter() {
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -15,6 +15,7 @@
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.core.JVM;
+import com.thoughtworks.xstream.core.util.Fields;
import com.thoughtworks.xstream.core.util.HierarchicalStreams;
import com.thoughtworks.xstream.core.util.PresortedMap;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
@@ -46,30 +47,8 @@
}
private final static Comparator NULL_MARKER = new NullComparator();
-
- private final static Field comparatorField;
- static {
- Field cmpField = null;
- try {
- Field[] fields = TreeMap.class.getDeclaredFields();
- for (int i = 0; i < fields.length; i++ ) {
- if (fields[i].getType() == Comparator.class) {
- // take the fist member of type "Comparator"
- cmpField = fields[i];
- cmpField.setAccessible(true);
- break;
- }
- }
- if (cmpField == null) {
- throw new ExceptionInInitializerError("Cannot detect comparator field of TreeMap");
- }
+ private final static Field comparatorField = Fields.locate(TreeMap.class, Comparator.class, false);
- } catch (SecurityException ex) {
- // ignore, no access possible with current SecurityManager
- }
- comparatorField = cmpField;
- }
-
public TreeMapConverter(Mapper mapper) {
super(mapper);
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -15,6 +15,7 @@
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.core.JVM;
+import com.thoughtworks.xstream.core.util.Fields;
import com.thoughtworks.xstream.core.util.PresortedSet;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
@@ -40,30 +41,8 @@
*/
public class TreeSetConverter extends CollectionConverter {
private transient TreeMapConverter treeMapConverter;
- private final static Field sortedMapField;
- static {
- Field smField = null;
- if (!JVM.hasOptimizedTreeSetAddAll()) {
- try {
- Field[] fields = TreeSet.class.getDeclaredFields();
- for (int i = 0; i < fields.length; i++ ) {
- if (SortedMap.class.isAssignableFrom(fields[i].getType())) {
- // take the fist member assignable to type "SortedMap"
- smField = fields[i];
- smField.setAccessible(true);
- break;
- }
- }
- if (smField == null) {
- throw new ExceptionInInitializerError("Cannot detect field of backing map of TreeSet");
- }
-
- } catch (SecurityException ex) {
- // ignore, no access possible with current SecurityManager
- }
- }
- sortedMapField = smField;
- }
+ private final static Field sortedMapField =
+ JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, SortedMap.class, false) : null;
public TreeSetConverter(Mapper mapper) {
super(mapper);
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -37,30 +37,8 @@
*/
public class EnumMapConverter extends MapConverter {
- private final static Field typeField;
- static {
- // field name is "keyType" in Sun JDK, but different in IKVM
- Field assumedTypeField = null;
- try {
- Field[] fields = EnumMap.class.getDeclaredFields();
- for (int i = 0; i < fields.length; i++ ) {
- if (fields[i].getType() == Class.class) {
- // take the fist member of type "Class"
- assumedTypeField = fields[i];
- assumedTypeField.setAccessible(true);
- break;
- }
- }
- if (assumedTypeField == null) {
- throw new ExceptionInInitializerError("Cannot detect key type of EnumMap");
- }
+ private final static Field typeField = Fields.locate(EnumMap.class, Class.class, false);
- } catch (SecurityException ex) {
- // ignore, no access possible with current SecurityManager
- }
- typeField = assumedTypeField;
- }
-
public EnumMapConverter(Mapper mapper) {
super(mapper);
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -39,29 +39,7 @@
*/
public class EnumSetConverter implements Converter {
- private final static Field typeField;
- static {
- // field name is "elementType" in Sun JDK, but different in Harmony
- Field assumedTypeField = null;
- try {
- Field[] fields = EnumSet.class.getDeclaredFields();
- for (int i = 0; i < fields.length; i++ ) {
- if (fields[i].getType() == Class.class) {
- // take the fist member of type "Class"
- assumedTypeField = fields[i];
- assumedTypeField.setAccessible(true);
- break;
- }
- }
- if (assumedTypeField == null) {
- throw new ExceptionInInitializerError("Cannot detect element type of EnumSet");
- }
- } catch (SecurityException ex) {
- // ignore, no access possible with current SecurityManager
- }
- typeField = assumedTypeField;
- }
-
+ private final static Field typeField = Fields.locate(EnumSet.class, Class.class, false);
private final Mapper mapper;
public EnumSetConverter(Mapper mapper) {
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -39,23 +39,12 @@
private ClassLoaderReference classLoaderReference;
private Mapper mapper;
- private static final Field HANDLER;
+ private static final Field HANDLER = Fields.locate(Proxy.class, InvocationHandler.class, false);
private static final InvocationHandler DUMMY = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
};
-
- static {
- Field field = null;
- try {
- field = Proxy.class.getDeclaredField("h");
- field.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new ExceptionInInitializerError(e);
- }
- HANDLER = field;
- }
/**
* @deprecated As of upcoming use {@link #DynamicProxyConverter(Mapper, ClassLoaderReference)}
@@ -131,10 +120,17 @@
}
Class[] interfacesAsArray = new Class[interfaces.size()];
interfaces.toArray(interfacesAsArray);
- Object proxy = Proxy.newProxyInstance(classLoaderReference.getReference(), interfacesAsArray, DUMMY);
+ Object proxy = null;
+ if (HANDLER != null) { // we will not be able to resolve references to the proxy
+ proxy = Proxy.newProxyInstance(classLoaderReference.getReference(), interfacesAsArray, DUMMY);
+ }
handler = (InvocationHandler) context.convertAnother(proxy, handlerType);
reader.moveUp();
- Fields.write(HANDLER, proxy, handler);
+ if (HANDLER != null) {
+ Fields.write(HANDLER, proxy, handler);
+ } else {
+ proxy = Proxy.newProxyInstance(classLoaderReference.getReference(), interfacesAsArray, handler);
+ }
return proxy;
}
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -10,7 +10,9 @@
*/
package com.thoughtworks.xstream.converters.reflection;
+import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
+import com.thoughtworks.xstream.core.util.Fields;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -32,22 +34,33 @@
public class AbstractAttributedCharacterIteratorAttributeConverter extends
AbstractSingleValueConverter {
+ private static final Map instanceMaps = new HashMap();
private static final Method getName;
static {
+ Method method = null;
try {
- getName = AttributedCharacterIterator.Attribute.class.getDeclaredMethod(
+ method = AttributedCharacterIterator.Attribute.class.getDeclaredMethod(
"getName", (Class[])null);
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ } catch (SecurityException e) {
+ // ignore for now
} catch (NoSuchMethodException e) {
- throw new ExceptionInInitializerError("Missing AttributedCharacterIterator.Attribute.getName()");
+ // ignore for now
}
+ getName = method;
}
private final Class type;
private transient Map attributeMap;
- private transient FieldDictionary fieldDictionary;
public AbstractAttributedCharacterIteratorAttributeConverter(final Class type) {
super();
+ if (!AttributedCharacterIterator.Attribute.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(type.getName()
+ + " is not a " + AttributedCharacterIterator.Attribute.class.getName());
+ }
this.type = type;
readResolve();
}
@@ -57,40 +70,72 @@
}
public String toString(final Object source) {
- AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute)source;
- try {
- if (!getName.isAccessible()) {
- getName.setAccessible(true);
+ return getName((AttributedCharacterIterator.Attribute)source);
+ }
+
+ private String getName(AttributedCharacterIterator.Attribute attribute) {
+ Exception ex = null;
+ if (getName != null) {
+ try {
+ return (String)getName.invoke(attribute, (Object[])null);
+ } catch (IllegalAccessException e) {
+ ex = e;
+ } catch (InvocationTargetException e) {
+ ex = e;
}
- return (String)getName.invoke(attribute, (Object[])null);
- } catch (IllegalAccessException e) {
- throw new ObjectAccessException(
- "Cannot get name of AttributedCharacterIterator.Attribute", e);
- } catch (InvocationTargetException e) {
- throw new ObjectAccessException(
- "Cannot get name of AttributedCharacterIterator.Attribute", e
- .getTargetException());
}
+ String s = attribute.toString();
+ String className = attribute.getClass().getName();
+ if (s.startsWith(className)) {
+ return s.substring(className.length()+1, s.length()-1);
+ }
+ throw new ConversionException("Cannot find name of attribute of type " + className, ex);
}
public Object fromString(final String str) {
- return attributeMap.get(str);
+ if (attributeMap.containsKey(str)) {
+ return attributeMap.get(str);
+ }
+ throw new ConversionException("Cannot find attribute of type " + type.getName() + " with name " + str);
}
private Object readResolve() {
- fieldDictionary = new FieldDictionary();
- attributeMap = new HashMap();
- for (final Iterator iterator = fieldDictionary.fieldsFor(type); iterator
- .hasNext();) {
- final Field field = (Field)iterator.next();
- if (field.getType() == type && Modifier.isStatic(field.getModifiers())) {
+ attributeMap = (Map)instanceMaps.get(type.getName());
+ if (attributeMap == null) {
+ attributeMap = new HashMap();
+ Field instanceMap = Fields.locate(type, Map.class, true);
+ if (instanceMap != null) {
try {
- final Object attribute = field.get(null);
- attributeMap.put(toString(attribute), attribute);
- } catch (IllegalAccessException e) {
- throw new ObjectAccessException("Cannot get object of " + field, e);
+ Map map = (Map)Fields.read(instanceMap, null);
+ if (map != null) {
+ boolean valid = true;
+ for (Iterator iter = map.entrySet().iterator(); valid && iter.hasNext(); ) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ valid = entry.getKey().getClass() == String.class && entry.getValue().getClass() == type;
+ }
+ if (valid) {
+ attributeMap.putAll(map);
+ }
+ }
+ } catch (ObjectAccessException e) {
}
}
+ if (attributeMap.isEmpty()) {
+ try {
+ Field[] fields = type.getDeclaredFields();
+ for(int i = 0; i < fields.length; ++i) {
+ if(fields[i].getType() == type == Modifier.isStatic(fields[i].getModifiers())) {
+ AttributedCharacterIterator.Attribute attribute =
+ (AttributedCharacterIterator.Attribute)Fields.read(fields[i], null);
+ attributeMap.put(toString(attribute), attribute);
+ }
+ }
+ } catch (SecurityException e) {
+ attributeMap.clear();
+ } catch (ObjectAccessException e) {
+ attributeMap.clear();
+ }
+ }
}
return this;
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java (2091 => 2092)
--- trunk/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -12,6 +12,7 @@
package com.thoughtworks.xstream.core.util;
import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
@@ -20,8 +21,29 @@
* wraps exception in XStreamExceptions.
*
* @author Joe Walnes
+ * @author Jörg Schaible
*/
public class Fields {
+ public static Field locate(Class definedIn, Class fieldType, boolean isStatic) {
+ Field field = null;
+ try {
+ Field[] fields = definedIn.getDeclaredFields();
+ for(int i = 0; i < fields.length; ++i) {
+ if (Modifier.isStatic(fields[i].getModifiers()) == isStatic) {
+ if (fieldType.isAssignableFrom(fields[i].getType())) {
+ field = fields[i];
+ }
+ }
+ }
+ if (field != null) {
+ field.setAccessible(true);
+ }
+ } catch (SecurityException e) {
+ // active SecurityManager
+ }
+ return field;
+ }
+
public static Field find(Class type, String name) {
try {
Field result = type.getDeclaredField(name);
@@ -30,12 +52,7 @@
}
return result;
} catch (NoSuchFieldException e) {
- throw new IllegalArgumentException("Could not access "
- + type.getName()
- + "."
- + name
- + " field: "
- + e.getMessage());
+ throw new IllegalArgumentException("Could not access " + type.getName() + "." + name + " field: " + e.getMessage());
}
}
Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java (2091 => 2092)
--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java 2013-07-04 22:18:43 UTC (rev 2091)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java 2013-07-04 23:12:27 UTC (rev 2092)
@@ -40,6 +40,7 @@
protected void setUp() throws Exception {
super.setUp();
+ // fonts should be serializable also with pure Java
xstream = new XStream(new PureJavaReflectionProvider());
in = new Font("Arial", Font.BOLD, 20);
}
To unsubscribe from this list please visit:
