com.thoughtworks.xstream.mapper.CannotResolveClassException
Asked Answered
M

2

10

This is the frist time I am trying XStream. But when I try to parse my xml file i am getting this exception :

Exception in thread "main" com.thoughtworks.xstream.mapper.CannotResolveClassException: root
    at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:79)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:45)
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:133)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1157)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1141)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1012)
    at com.mmm.transport.se.xmleditor.xml.TestXML.test(TestXML.java:20)
    at com.mmm.transport.se.xmleditor.domain.Main.main(Main.java:13)

So we can see that the error is on row 20 in my testXML class. And it looks like this :

public class TestXML {

    public void test() throws FileNotFoundException {

        FileReader reader = new FileReader("xmlFiles/CoreDatamodel.xml");

        XStream xstream = new XStream();
        xstream.processAnnotations(Properties.class);
        xstream.processAnnotations(Parameters.class);
        xstream.processAnnotations(ObjType.class);
        xstream.processAnnotations(Type.class);
        Type data = (Type) xstream.fromXML(reader);

        System.out.println(data);
    }

}

And row 20 is the this line : xstream.processAnnotations(Parameters.class);

@XStreamAlias("param")
public class Parameters {

    @XStreamAlias("DATATYPE")
    private String datatype;
    @XStreamAlias("DESCRIPTION")
    private String description;
    @XStreamAlias("MIN_NO")
    private String min_no;
    @XStreamAlias("MAX_NO")
    private String max_no;
    @XStreamAlias("ORDER1")
    private String order1;
    @XStreamAlias("NESTED")
    private String nested;
    @XStreamAlias("DEFAULT1")
    private String default1;
    @XStreamAlias("FORMAT")
    private String format;
    @XStreamAlias("PARAMETER")
    private String parameter;

    public Parameters(String datatype, String description, String min_no,
            String max_no, String order1, String nested, String default1,
            String format, String parameter) {
        super();

        setDatatype(datatype);
        setDescription(description);
        setMin_no(min_no);
        setMax_no(max_no);
        setOrder1(order1);
        setNested(nested);
        setDefault1(default1);
        setFormat(format);
        setParameter(parameter);

    } //Getters and setters..

And the xml looks like this :

- <root>
- <info>
  <CORE_NAME>DataModel_Core</CORE_NAME> 
  <CORE_VERSION>..</CORE_VERSION> 
  <CORE_PRODUCT_ID>...</CORE_PRODUCT_ID> 
  <ADAPTATION_NAME /> 
  <ADAPTATION_VERSION /> 
  <ADAPTATION_PRODUCT_ID /> 
  </info>
- <type>
  <OBJECT_TYPE>data</OBJECT_TYPE> 
- <prop>
  <DESCRIPTION>Site parameters</DESCRIPTION> 
  <PARENT>NULL</PARENT> 
  <VIRTUAL>0</VIRTUAL> 
  <VISIBLE>1</VISIBLE> 
  <PICTURE>NULL</PICTURE> 
  <HELP>10008</HELP> 
  <MIN_NO>1</MIN_NO> 
  <MAX_NO>1</MAX_NO> 
  <NAME_FORMAT>NULL</NAME_FORMAT> 
  </prop>
- <param>
  <PARAMETER>nidRbc</PARAMETER> 
  <DATA_TYPE>INTEGER</DATA_TYPE> 
  <DESCRIPTION>RBC identity</DESCRIPTION> 
  <MIN_NO>1</MIN_NO> 
  <MAX_NO>1</MAX_NO> 
  <ORDER1>1</ORDER1> 
  <NESTED>0</NESTED> 
  <DEFAULT1>NULL</DEFAULT1> 
  <FORMAT>0:16382</FORMAT> 
  </param>
</type>

Other classes involved looks like this :

public class Type {

    @XStreamImplicit(itemFieldName = "type")
    private List types = new ArrayList();

}

public class ObjType {

    @XStreamAlias("OBJECT_TYPE")
    private String objectType;

    public ObjType() {

    } // Getters and setters

@XStreamAlias("prop")
public class Properties {

    @XStreamAlias("DESCRIPTION")
    private String description;
    @XStreamAlias("PARENT")
    private String parent;
    @XStreamAlias("VIRTUAL")
    private String virtual;
    @XStreamAlias("VISIBLE")
    private String visible;
    @XStreamAlias("PICTURE")
    private String picture;
    @XStreamAlias("HELP")
    private String help;
    @XStreamAlias("MIN_NO")
    private String min_no;
    @XStreamAlias("MAX_NO")
    private String max_no;
    @XStreamAlias("NAME_FORMAT")
    private String name_format;
    public static Properties instance = null;

    public static Properties getInstance() {

        if (instance == null) {

            instance = new Properties();

        }

        return instance;
    }

    public Properties() {

    } // Getters and Setters.

Whats the cause of this error?

Mn answered 22/1, 2014 at 12:31 Comment(0)
B
10

The reason you get this exception is because you do not have a representation for the xml elements root and info of your xml.

So when XStream is reading that xml file it is searching for a class matching the root element. If you do not have an alias / mapping defined, it will try the tag name as a class name.

So, instead of:

public class Type {
    @XStreamImplicit(itemFieldName = "type")
    private List types = new ArrayList();
}

use something like that:

@XStreamAlias("root")
public class Type {
    private Info info;

    @XStreamImplicit(itemFieldName = "type")
    private List types = new ArrayList();
}

private class Info {
    // ... define the attributes for the info element here.
}

For your reference I have formatted your xml to make things more readable:

<root>
    <info>
        <CORE_NAME>DataModel_Core</CORE_NAME> 
        <CORE_VERSION>..</CORE_VERSION> 
        <CORE_PRODUCT_ID>...</CORE_PRODUCT_ID> 
        <ADAPTATION_NAME /> 
        <ADAPTATION_VERSION /> 
        <ADAPTATION_PRODUCT_ID /> 
    </info>
    <type>
        <OBJECT_TYPE>data</OBJECT_TYPE>
        <prop>
            <DESCRIPTION>Site parameters</DESCRIPTION> 
            <PARENT>NULL</PARENT> 
            <VIRTUAL>0</VIRTUAL> 
            <VISIBLE>1</VISIBLE> 
            <PICTURE>NULL</PICTURE> 
            <HELP>10008</HELP> 
            <MIN_NO>1</MIN_NO> 
            <MAX_NO>1</MAX_NO> 
            <NAME_FORMAT>NULL</NAME_FORMAT> 
        </prop>
        <param>
            <PARAMETER>nidRbc</PARAMETER> 
            <DATA_TYPE>INTEGER</DATA_TYPE> 
            <DESCRIPTION>RBC identity</DESCRIPTION> 
            <MIN_NO>1</MIN_NO> 
            <MAX_NO>1</MAX_NO> 
            <ORDER1>1</ORDER1> 
            <NESTED>0</NESTED> 
            <DEFAULT1>NULL</DEFAULT1> 
            <FORMAT>0:16382</FORMAT> 
        </param>
    </type>
</root>
Boisvert answered 23/1, 2014 at 6:1 Comment(3)
Can I avoid to use @XStreamAlias("XXXX") attributes on the model?Metabolite
I'm sorry, I spoke (typed) incorrectly... you don't need XStreamAlias for property names that match their XML element/attribute tag name counterpart, but the same is not true of class names. Without the alias being set, XStream generates (when marshalling) or expects (when unmarshalling) tags with the fully qualified classname, as experienced by @YeswanthDevisetty below.Beard
@mathias class should be public?Auster
W
1

I was recently facing the same issue. The problem being, in the xml request I didn't give the complete qualified name.

<FeatureContextRequest>
  <featureRequestType>GLOBAL</featureRequestType>
</FeatureContextRequest>

After realizing the issue, I've changed it to

<com.xxxx.yyyy.services.features.FeatureContextRequest>
  <featureRequestType>GLOBAL</featureRequestType>
</com.xxxx.yyyy.services.features.FeatureContextRequest>

It's working fine from then on.

Wingard answered 27/3, 2014 at 9:1 Comment(3)
this is not a good solution for me, in most cases the xml is produced from others services.Metabolite
@Metabolite is right. When we receive xml file it means we are cosumer and we don't have to modify this xml unless we are obliged to.Debor
Don't alter xml string, instead, before calling fromXml(), use xstream.alias("FeatureContextRequest", FeatureContextRequest.class);Scurrilous

© 2022 - 2024 — McMap. All rights reserved.