Title: [2090] trunk/xstream/src: Support null as value of ClassLoaderReference to refer bootstrap class loader.
Revision
2090
Author
joehni
Date
2013-07-04 15:53:28 -0500 (Thu, 04 Jul 2013)

Log Message

Support null as value of ClassLoaderReference to refer bootstrap class loader. Fix invalid ClassLoaderTest.

Modified Paths

Diff

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java (2089 => 2090)


--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java	2013-07-03 22:25:40 UTC (rev 2089)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java	2013-07-04 20:53:28 UTC (rev 2090)
@@ -14,7 +14,9 @@
 import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
 import com.thoughtworks.xstream.core.ClassLoaderReference;
-import com.thoughtworks.xstream.core.util.Primitives;
+import com.thoughtworks.xstream.mapper.CannotResolveClassException;
+import com.thoughtworks.xstream.mapper.DefaultMapper;
+import com.thoughtworks.xstream.mapper.Mapper;
 
 /**
  * Converts a java.lang.Class to XML.
@@ -26,7 +28,7 @@
  */
 public class JavaClassConverter extends AbstractSingleValueConverter {
 
-    private ClassLoaderReference classLoaderReference;
+    private Mapper mapper;
 
     /**
      * Construct a JavaClassConverter.
@@ -34,7 +36,7 @@
      * @since upcoming
      */
     public JavaClassConverter(ClassLoaderReference classLoaderReference) {
-        this.classLoaderReference = classLoaderReference;
+        mapper = new DefaultMapper(classLoaderReference);
     }
 
     /**
@@ -54,32 +56,9 @@
 
     public Object fromString(String str) {
         try {
-            return loadClass(str);
-        } catch (ClassNotFoundException e) {
-            throw new ConversionException("Cannot load java class " + str, e);
+            return mapper.realClass(str);
+        } catch (CannotResolveClassException e) {
+            throw new ConversionException("Cannot load java class " + str, e.getCause());
         }
     }
-
-    private Class loadClass(String className) throws ClassNotFoundException {
-        Class resultingClass = Primitives.primitiveType(className);
-        if( resultingClass != null ){
-            return resultingClass;
-        }
-        int dimension;
-        for(dimension = 0; className.charAt(dimension) == '['; ++dimension);
-        if (dimension > 0) {
-            final ClassLoader classLoaderToUse;
-            if (className.charAt(dimension) == 'L') {
-                String componentTypeName = className.substring(dimension + 1, className.length() - 1);
-                classLoaderToUse = classLoaderReference
-                    .getReference()
-                    .loadClass(componentTypeName)
-                    .getClassLoader();
-            } else {
-                classLoaderToUse = null;
-            }
-            return Class.forName(className, false, classLoaderToUse);
-        }
-        return classLoaderReference.getReference().loadClass(className);
-    }
 }

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java (2089 => 2090)


--- trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java	2013-07-03 22:25:40 UTC (rev 2089)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java	2013-07-04 20:53:28 UTC (rev 2090)
@@ -50,6 +50,7 @@
 import com.thoughtworks.xstream.core.ClassLoaderReference;
 import com.thoughtworks.xstream.core.JVM;
 import com.thoughtworks.xstream.core.util.DependencyInjectionFactory;
+import com.thoughtworks.xstream.core.util.TypedNull;
 
 
 /**
@@ -88,9 +89,11 @@
         annotatedTypes.add(Object.class);
         setupMappers();
         locked = true;
+        
+        final ClassLoader classLoader = classLoaderReference.getReference();
         arguments = new Object[]{
             this, classLoaderReference, reflectionProvider, converterLookup, new JVM(),
-            classLoaderReference.getReference()};
+            classLoader != null ? classLoader : new TypedNull(ClassLoader.class)};
     }
 
     /**

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java (2089 => 2090)


--- trunk/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java	2013-07-03 22:25:40 UTC (rev 2089)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java	2013-07-04 20:53:28 UTC (rev 2090)
@@ -14,6 +14,7 @@
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.SingleValueConverter;
 import com.thoughtworks.xstream.core.ClassLoaderReference;
+import com.thoughtworks.xstream.core.util.Primitives;
 
 
 /**
@@ -29,7 +30,7 @@
     static {
         String packageName = DefaultMapper.class.getName();
         int idx = packageName.indexOf(".xstream.");
-        XSTREAM_PACKAGE_ROOT = idx > 0 ? packageName.substring(0, idx+9) : null;
+        XSTREAM_PACKAGE_ROOT = idx > 0 ? packageName.substring(0, idx+9) : ".N/A";
     }
     
     private final ClassLoaderReference classLoaderReference;
@@ -48,7 +49,7 @@
     /**
      * Construct a DefaultMapper.
      * 
-     * @param classLoader the classloader used by the XStream instance.
+     * @param classLoader the ClassLoader used by the XStream instance.
      * @deprecated As of upcoming use {@link #DefaultMapper(ClassLoaderReference)}
      */
     public DefaultMapper(ClassLoader classLoader) {
@@ -60,16 +61,20 @@
     }
 
     public Class realClass(String elementName) {
+        Class resultingClass = Primitives.primitiveType(elementName);
+        if( resultingClass != null ){
+            return resultingClass;
+        }
         try {
+            boolean initialize = true;
+            final ClassLoader classLoader;
             if (elementName.startsWith(XSTREAM_PACKAGE_ROOT)) {
-                return DefaultMapper.class.getClassLoader().loadClass(elementName);
-            } else if (elementName.charAt(0) != '[') {
-                return classLoaderReference.getReference().loadClass(elementName);
-            } else if (elementName.endsWith(";")) {
-                return Class.forName(elementName.toString(), false, classLoaderReference.getReference());
-            } else { 
-                return Class.forName(elementName.toString());
+                classLoader = DefaultMapper.class.getClassLoader();
+            } else {
+                classLoader = classLoaderReference.getReference();
+                initialize = elementName.charAt(0) == '[';
             }
+            return Class.forName(elementName, initialize, classLoader);
         } catch (ClassNotFoundException e) {
             throw new CannotResolveClassException(elementName);
         }

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java (2089 => 2090)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java	2013-07-03 22:25:40 UTC (rev 2089)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java	2013-07-04 20:53:28 UTC (rev 2090)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -11,20 +11,49 @@
  */
 package com.thoughtworks.acceptance;
 
-public class ClassLoaderTest extends AbstractAcceptanceTest {
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 
-    private String classLoaderCall;
+import com.thoughtworks.xstream.mapper.CannotResolveClassException;
 
-    public void testAllowsClassLoaderToBeOverriden() {
-        xstream.setClassLoader(new MockClassLoader());
-        assertEquals("hello", xstream.fromXML("<java.BANG.String>hello</java.BANG.String>"));
-        assertEquals("java.BANG.String", classLoaderCall);
-    }
 
-    private class MockClassLoader extends ClassLoader {
-        public Class loadClass(String name) {
-            classLoaderCall = name;
-            return String.class;
+public class ClassLoaderTest extends AbstractAcceptanceTest {
+
+    public void testAllowsClassLoaderToBeOverriden() throws MalformedURLException {
+        String name = "com.thoughtworks.proxy.kit.SimpleReference";
+        String xml = "<com.thoughtworks.proxy.kit.SimpleReference/>";
+        try {
+            xstream.fromXML(xml);
+            fail("Thrown " + CannotResolveClassException.class.getName() + " expected");
+        } catch (final CannotResolveClassException e) {
+            assertEquals(name, e.getMessage());
         }
+        
+        File proxyToys = new File("target/lib/proxytoys-0.2.1.jar");
+        ClassLoader classLoader = new URLClassLoader(
+            new URL[]{proxyToys.toURI().toURL()}, getClass().getClassLoader());
+        // will not work, since class has already been cached
+        xstream.setClassLoader(classLoader);
+        
+        try {
+            xstream.fromXML(xml);
+            fail("Thrown " + CannotResolveClassException.class.getName() + " expected");
+        } catch (final CannotResolveClassException e) {
+            assertEquals(name, e.getMessage());
+        }
+        
+        xstream = createXStream();
+        xstream.setClassLoader(classLoader);
+        assertEquals(name, xstream.fromXML(xml).getClass().getName());
+        
+        xstream = createXStream();
+        try {
+            xstream.fromXML(xml);
+            fail("Thrown " + CannotResolveClassException.class.getName() + " expected");
+        } catch (final CannotResolveClassException e) {
+            assertEquals(name, e.getMessage());
+        }
     }
 }

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to