Deserializing XML using XStream does not work in OSGi (Java 1.4)

2.5k views Asked by At

I created some OSGi-bundles. One of these has a function to export data to xml using XStream. It just works fine. Also importing again when using the Bundle as library and not within an OSGi context, works.

But if I call my import within another bundle I get a "com.thoughtworks.xstream.converters.ConversionException" with the follwing Debugging Information printed out:

---- Debugging information ----
message             : Cannot find class ChildDate
cause-exception     : com.thoughtworks.xstream.converters.reflection.ObjectAccessException
cause-message       : Cannot find class ChildData
class               : ChildData
required-type       : ChildData
path                : /ParentData/ChildData
-------------------------------
message             : Could not call ParentData.readObject()
cause-exception     : com.thoughtworks.xstream.converters.ConversionException
cause-message       : Cannot find class ParentData : Cannot find class ChildData
class               : ParentData
required-type       : ChildData
path                : /ParentData/ChildData
-------------------------------

I think it's a similar problem to this: XStream and OSGi or this: CannotResolveClassException in OSGi environment

So I tried to solve it setting the ClassLoader. But it does not work.

Parts of my ParentData class:

public class ParentData implements Serializable {
  // [...]
  private static ClassLoader classLoaderForImport = ParentData.class.getClassLoader();
  // [...]
  public static void setClassLoaderForImport(ClassLoader classLoaderForImport) {
    ParentData.classLoaderForImport = classLoaderForImport;
  }
  // [...]
  public static Lumicon importFromXMLFile(String path) {
    return importFromFile(new DomDriver(), path);
  }
  private static ParentData importFromFile(HierarchicalStreamDriver driver, String path) {
    try {
      XStream xstream = new XStream(driver);
      //set the classloader as the default one won't work in any case
      xstream.setClassLoader(ParentData.classLoaderForImport);
      xstream.alias("ParentData", classLoaderForImport.loadClass(ParentData.class.getName()));//ParentData.class);
      xstream.alias("ChildData", classLoaderForImport.loadClass(ChildData.class.getName()));//ChildData.class);
      Reader reader = new FileReader(path);
      Object object = xstream.fromXML(reader);
      return (ParentData) object;
    } catch (ClassNotFoundException ex) {
      System.out.println("This did not work.");
    } catch (FileNotFoundException e) {
      System.out.println("File " + path + " not found.");
    }
  }
// [...]
}

The function xstream.fromXML(reader) does not work, but classLoaderForImport.loadClass(ChildData.class.getName()) doesn't fail.

This is how I call it from another Bundle:

ParentData.setClassLoaderForImport(ParentData.class.getClassLoader());
data = ParentData.importFromXMLFile(path); // this is where the Exception happens

I also tried this.getClass().getClassLoader() and ChildData.class.getClassLoader()

Could it be, that this does not work, because this function is called from a third bundle?

Some more Info:

  • Java version: 1.4 (no, I can not upgrade to 1.5 or 1.6)
  • Execution environment: J2SE-1.6
  • Maven Version: 2.2.1
  • Running with Pax Runner (1.5.0) from OPS4J - http://www.ops4j.org
  • OSGi: Equinox 3.6.0
  • XStream 1.3.1 (com.springsource.com.thoughtworks.xstream)

Any help would be very welcome!

1

There are 1 answers

1
Angelo van der Sijpt On BEST ANSWER

Assuming your question contains all the relevant code, the problem is given away by the following:

Could not call ParentData.readObject()

You have declared that your ParentData implements Serializable. Although the Serializable interface does not include any methods, both Java serialization and XStream expect a readObject and a writeObject. I'm a little rusty on the exact situations in which these are mandatory, but I would suggest you to remove the implements Serializable from the ParentData class.