2015-01-05 2 views
3

XStream serialization library претендует на надежную сериализацию сложных объектов Java из коробки (например, никаких изменений в объектах или необходимости отображения). В частности, согласно XStream docs, XStream может обрабатывать ссылки на круглые объекты.Как обращаться с циклическими ссылками в XStream?

Так что я написал тест, чтобы проверить это - я попытался сериализации довольно сложную структуру данных (LinkedHashMultimap), который включал в себя ссылку на iteself:

import com.google.common.collect.LinkedHashMultimap; 
import com.thoughtworks.xstream.XStream; 

public class SerializationTest { 

    public static void main(String[] args0) { 

     // Create LinkedHashMultimap to serialize 
     LinkedHashMultimap<String, Object> outObj = LinkedHashMultimap.create(); 
     outObj.put("x", 1); 
     outObj.put("x", "abc"); 
     outObj.put("y", outObj); // Add a self-reference 

     // Try to serialize 
     XStream xstream = new XStream(); 
     String xml = xstream.toXML(outObj); 
     System.out.println(xml); // Print XML to console for a quick peek 

     // Try to deserialize - ERROR HERE!!! 
     LinkedHashMultimap<String, Object> inObj = (LinkedHashMultimap<String, Object>)xstream.fromXML(xml); 

     System.out.println(inObj); 
    } 
} 

Сериализованный объект XML выглядит следующим образом:

<com.google.common.collect.LinkedHashMultimap serialization="custom"> 
    <unserializable-parents/> 
    <com.google.common.collect.LinkedHashMultimap> 
    <default/> 
    <int>2</int> 
    <int>2</int> 
    <string>x</string> 
    <string>y</string> 
    <int>3</int> 
    <string>x</string> 
    <int>1</int> 
    <string>x</string> 
    <string>abc</string> 
    <string>y</string> 
    <com.google.common.collect.LinkedHashMultimap reference="../.."/> 
    </com.google.common.collect.LinkedHashMultimap> 
</com.google.common.collect.LinkedHashMultimap> 

Однако десериализации (т.е. вызов xstream.fromXML()) не с NullPointerException исключением:

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: Could not call com.google.common.collect.LinkedHashMultimap.readObject() : null 
---- Debugging information ---- 
message    : Could not call com.google.common.collect.LinkedHashMultimap.readObject() 
cause-exception  : java.lang.NullPointerException 
cause-message  : null 
class    : com.google.common.collect.LinkedHashMultimap 
required-type  : com.google.common.collect.LinkedHashMultimap 
converter-type  : com.thoughtworks.xstream.converters.reflection.SerializableConverter 
path    : /com.google.common.collect.LinkedHashMultimap/com.google.common.collect.LinkedHashMultimap 
line number   : 15 
version    : 1.4.7 
------------------------------- 
    at com.thoughtworks.xstream.converters.reflection.SerializationMethodInvoker.callReadObject(SerializationMethodInvoker.java:119) 
    at com.thoughtworks.xstream.converters.reflection.SerializableConverter.doUnmarshal(SerializableConverter.java:454) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) 
Disconnected from the target VM, address: '127.0.0.1:50107', transport: 'socket' 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) 
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1185) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1169) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1040) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1031) 
    at SerializationTest3.main(SerializationTest3.java:18) 
Caused by: java.lang.NullPointerException 
    at com.google.common.collect.AbstractMapBasedMultimap$AsMap.hashCode(AbstractMapBasedMultimap.java:1289) 
    at com.google.common.collect.AbstractMultimap.hashCode(AbstractMultimap.java:228) 
    at com.google.common.collect.LinkedHashMultimap.hashCode(LinkedHashMultimap.java:81) 
    at com.google.common.collect.Hashing.smearedHash(Hashing.java:51) 
    at com.google.common.collect.LinkedHashMultimap$ValueSet.add(LinkedHashMultimap.java:416) 
    at com.google.common.collect.LinkedHashMultimap.readObject(LinkedHashMultimap.java:574) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.thoughtworks.xstream.converters.reflection.SerializationMethodInvoker.callReadObject(SerializationMethodInvoker.java:113) 
    ... 13 more 

Так кто-нибудь знает, почему это происходит? И как решить это?

+0

Человек ты все еще там? Скажи мне, как ты это решил. –

+0

использовать xstream.setMode (XStream.XPATH_RELATIVE_REFERENCES); –

ответ

1

Использование:

XStream xstream = new XStream(); 
xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); 
Смежные вопросы