pclem12 pclem12 - 3 months ago 20
Java Question

XStream class cannot be resolved

I'm getting an XStream error with the following setup. I must be crazy. What's wrong?

The request class

@XStreamAlias("RequestTO")
public class RequestTO {

@XStreamImplicit
private List<SkuMerchTO> skuNumbers;
...
}


The nested object class

@XStreamAlias("skuMerch")
public class SkuMerchTO {

@XStreamAlias("skuNumber")
@XStreamAsAttribute
private Integer skuNumber;

@XStreamAlias("dept")
@XStreamAsAttribute
private Short department;

@XStreamAlias("class")
@XStreamAsAttribute
private Short cls;

@XStreamAlias("subClass")
@XStreamAsAttribute
private Short subClass;
...
}


XStream code to decode the XML to an object:

XStream stream = new XStream();
stream.processAnnotations(SkuMerchTO.class);
stream.processAnnotations(RequestTO.class);
RequestTO request = (RequestTO)stream.fromXML(requestXml);


XML input string:

<RequestTO>
<skuMerch skuNumber="123456" dept="1" class="2" subClass="3"/>
<skuMerch skuNumber="234567" dept="4" class="5" subClass="6"/>
</RequestTO>


Error in Stacktrace:

---- Debugging information ----

message : 2 : 2

cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException

cause-message : 2 : 2

class : [...]RequestTO

required-type : [...]SkuMerchTO

path : /RequestTO/skuNumberList/skuMerch

line number : 3

.-------------------------------

com.thoughtworks.xstream.converters.ConversionException: 2 : 2 : 2 : 2

---- Debugging information ----

message : 2 : 2

cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException

cause-message : 2 : 2

class : [...]RequestTO

required-type :[..]SkuMerchTO

path : /RequestTO/skuNumberList/skuMerch

line number : 3

.-------------------------------

If I create the objects and do toXML I get this:

<RequestTO>
<skuMerch skuNumber="0" dept="1" class="2" subClass="2"/>
<skuMerch skuNumber="1" dept="1" class="2" subClass="2"/>
<skuMerch skuNumber="2" dept="1" class="2" subClass="2"/>
</RequestTO>


EDIT: The hilarious thing is, if do this:

stream.fromXML(stream.toXML(object));


It still fails on the from XML part!

Answer

The attribute named class has a special meaning to XStream, this question suggests that you can tell XStream to use a different attribute for this purpose via something like

stream.aliasSystemAttribute("__class", "class");

This would cause XStream to use __class as the "special" attribute, and treat class as a normal one. Or, if you know you don't need the XStream magic handling of class for any of your objects you can say

stream.aliasSystemAttribute(null, "class");

to tell it not to use this feature at all.

You may also need to use itemFieldName="skuMerch" on the @XStreamImplicit annotation, as per the XStream annotation tutorial.