XStream
  1. XStream
  2. XSTR-185

ClassNotFoundException when deserializing Class array type

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.1.1
    • Component/s: None
    • Labels:
      None
    • JDK version and platform:
      1.4.2_06 for Windows

      Description

      The problem occurs when you deserialize a Class describing an array of objects. For instance MyClass[].class.

      The test case would be:

      // Class.forName(BasicInxDTO[].class.getName());

      FileReader in = new FileReader("test.xml");
      Object o = xstream.fromXML(in);
      in.close();

      test.xml content:
      <java-class>[Lcom.mycompany.MyClass;</java-class>

      You get a ClassNotFoundException. The tricky thing is if you uncomment the Class.forName line above, it will work perfectly. It also works with classes coming from the JDK (java.lang for instance). So it is important that the test uses a class defined for the test.

      The problematic code comes from the JavaClassConverter:

      protected Object fromString(String str) {
      try

      { return str.equals("void") ? void.class : str.equals("byte") ? byte.class : str.equals("int") ? int.class : str.equals("long") ? long.class : str.equals("float") ? float.class : str.equals("boolean") ? boolean.class : str.equals("double") ? double.class : str.equals("char") ? char.class : str.equals("short") ? short.class : classLoader.loadClass(str);// <- Here }

      catch (ClassNotFoundException e)

      { throw new ConversionException("Cannot load java class " + str, e); }
      }

      It seems that the class loader (at least the Sun class loader) is not able to instantiate an array class. The fact that it works when the class is already loaded is probably that it's found in the class loader class cache.

      The proposed fix is:

      protected Object fromString(String str) {
      try { return str.equals("void") ? void.class : str.equals("byte") ? byte.class : str.equals("int") ? int.class : str.equals("long") ? long.class : str.equals("float") ? float.class : str.equals("boolean") ? boolean.class : str.equals("double") ? double.class : str.equals("char") ? char.class : str.equals("short") ? short.class : Class.forName(str, false, classLoader); // <- The fix } catch (ClassNotFoundException e) { throw new ConversionException("Cannot load java class " + str, e); }

      }

      It goes through the normal class loading process and arrays are correctly handled.

        People

        • Assignee:
          Unassigned
          Reporter:
          Henri Tremblay
        • Votes:
          1 Vote for this issue
          Watchers:
          0 Start watching this issue

          Dates

          • Created:
            Updated:
            Resolved: