1. Compatibility
  2. Serialization
  3. XML specifics
  4. JSON specifics
  5. Comparison to other products
  6. Scalability
  7. Uses of XStream

Compatibility

Which JDK is required to use XStream?

1.3 or later.

Does XStream behave differently across different JVMs?

XStream has two modes of operation: Pure Java and Enhanced. In pure Java mode, XStream behaves in the same way across different JVMs, however it's features are limited to what reflection allows, meaning it cannot serialize certain classes or fields. In enhanced mode, XStream does not have these limitations, however this mode of operation is not available to all JVMs.

Which JVMs allow XStream to operate in enhanced mode?

Currently on the Sun, Apple, HP, IBM and Blackdown 1.4 JVMs and onwards. Also for Hitachi and SAP from 1.5 and onwards. Support for BEA JRockit starting with R25.1.0. For all other JVMs, XStream should be used in pure Java mode.

What are the advantages of using enhanced mode over pure Java mode?

FeaturePure JavaEnhanced Mode
Public classesYesYes
Non public classesNoYes
Static inner classesYesYes
Non-static inner classesNoYes
Anonymous inner classesNoYes
With default constructorYesYes
Without default constructorNoYes
Private fieldsYesYes
Final fieldsYes >= JDK 1.5Yes

Are there plans to provide enhanced mode support to other JVMs?

Yes. Let us know which JVM you would like supported.

When should I use XStream not in enhanced mode?

Running XStream in a secured environment can prevent XStream from running in enhanced mode. This is especially true when running XStream in an applet. You may also try to use the JavaBeanConverter as alternative to the ReflectionConverter running in enhanced or pure Java mode.

Which permissions does XStream need when running with an active SecurityManager?

This depends on the mode XStream is running in. Refer to the SecurityManagerTest for details.

Why does XStream 1.2 no longer read XML generated with XStream 1.1.x?

The architecture in XStream has slightly changed. Starting with XStream 1.2 the HierarchicalStreamDriver implementation is responsible to ensure that XML tags and attributes are valid names in XML, in XStream 1.1.x this responsibility was part of the ClassMapper implementations. Under some rare circumstances this will result in an unreadable XML due to the different processing order in the workflow of such problematic tag names.

You can run XStream in 1.1 compatibility mode though:

XStream xstream = new XStream(new XppDriver(new XStream11XmlFriendlyReplacer())) {
    protected boolean useXStream11XmlFriendlyMapper() {
        return true;
    }
};

XStream 1.3 ignores suddenly annotated converters (@XStreamConverter and @XStreamConverters)?

XStream treats now all annotations the same and therefore it no longer auto-detects any annotation by default. You can configure XStream to run in auto-detection mode, but be aware if the implications. As alternative you might register the deprecated AnnotationReflectionConverter, that was used for XStream pre 1.3.x, but as drawback the functionality to register a local converter with XStream.registerLocalConverter will no longer work.

Serialization

How do I specify that a field should not be serialized?

Make it transient, specify it with XStream.omitField() or annotate it with @XStreamOmitField

How do I initialize a transient field at deserialization?

XStream uses the same mechanism as the JDK serialization. Example:

class ThreadAwareComponent {
  private transient ThreadLocal component;
  // ...
  private Object readResolve() {
    component = new ThreadLocal();
    return this;
  }
}

XStream is not calling the default constructor during deserialization.

This is, in fact, the same case as above. XStream uses the same mechanism as the JDK serialization. When using the enhanced mode with the optimized reflection API, it does not invoke the default constructor. The solution is to implement the readResolve method as above:

class MyExecutor {
  private Object readResolve() {
    // do what you need to do here
    System.out.println("After instantiating MyExecutor");
    // at the end returns itself
    return this;
  }
}

What do serialized collections look like?

Example:

class Person {
  private String name;
  private List toys = new ArrayList();
  // ...
}

class Computer {
  String type;
}

class Car {
  String color;
}

xstream.alias("person", Person.class);
xstream.alias("computer", Computer.class);
xstream.alias("car", Car.class);

Person person = new Person("Joe");
person.addToy(new Computer("apple"));
person.addToy(new Computer("spectrum"));
person.addToy(new Car("blue"));

String xml = xstream.toXML(joe);

Results in:

<person>
  <name>Joe</name>
  <toys>
    <computer>
      <type>apple</type>
    </computer>
    <computer>
      <type>spectrum</type>
    </computer>
    <car>
      <color>blue</color>
    </car>
  </toys>
</person>

Note, that it is possible to configure XStream to omit the container element toys using implicit collections.

Do my classes have to implement Serializable if XStream is to serialize them?

No.

Can dynamic proxies be serialized?

Yes.

Can CGLIB proxies be serialized?

Only limitedly. A proxy generated with the CGLIB Enhancer is supported, if the proxy uses only one callback and the proxy instance can be generated without additional constructor arguments.

Serialization fails with NoSuchMethodError: net.sf.cglib.proxy.Enhancer.isEnhanced(Ljava/lang/Class;)Z

XStream uses this method to detect a CGLIB-enhanced proxy. Unfortunately the method is not available in the cglib-2.0 version. Since this version is many years old and the method is available starting with cglib-2.0.1, please consider an upgrade of the dependency, it works usually smoothly.

Can I select the field order in which XStream serializes objects?

Yes. XStream's ReflectionConverter uses the defined field order by default. You can override it by using an specific FieldKeySorter:

SortableFieldKeySorter sorter = new SortableFieldKeySorter();
sorter.registerFieldOrder(MyType.class, new String[] { "firstToSerialize", "secondToSerialize", "thirdToSerialize" });
xstream = new XStream(new Sun14ReflectionProvider(new FieldDictionary(sorter)));

How does XStream deal with newer versions of classes?

For more advanced class migrations, you may

Future versions of XStream will include features to make these type of migrations easier.

How does XStream cope with isolated class loaders?

Serializing an object graph is never a problem, even if the classes of those objects have been loaded by a different class loader. The situation changes completely at deserialization time. In this case you must set the class loader to use with:

xstream.setClassLoader(yourClassLoader);

Although XStream caches a lot of type related information to gain speed, it keeps those information in tables with weak references that should be cleaned by the garbage collector when the class loader is freed.

XML specifics

Why does XStream not respect the encoding in the XML declaration?

XStream architecture is based on IO Readers and Writers, while the XML declaration is the responsibility of XML parsers. XStream all HierarchicalStreamDriver implementation respect the encoding since version 1.3, but only if you provide an InputStream. If XStream consumes a Reader you have to initialize the reader with the appropriate encoding yourself, since it is now the reader's task to perform the encoding and no XML parser can change the encoding of a Reader and any encoding definition in the XML header will be ignored.

Why does XStream not write a XML declaration?

XStream is designed to write XML snippets, so you can embed its output into an existing stream or string. You can write the XML declaration yourself into the Writer before using it to call XStream.toXML(writer).

Why does XStream not write XML in UTF-8?

XStream does no character encoding by itself, it relies on the configuration of the underlying XML writer. By default it uses its own PrettyPrintWriter which writes into the default encoding of the current locale. To write UTF-8 you have to provide a Writer with the appropriate encoding yourself.

Why do field names suddenly have double underscores in the generated XML?

XStream maps Java class names and field names to XML tags or attributes. Unfortunately this mapping cannot be 1:1, since some identifiers of Java contain a dollar sign which is invalid in XML names. Therefore XStream uses an XmlFriendlyReplacer to replace this character with a replacement. By default this replacement uses an underscore and therefore the replacer must escape the underscore itself also. You may provide a different configured instance of the XmlFriendlyReplacer or a complete own implementation, but you must ensure, that the resulting names are valid for XML.

XStream fails to unmarshal my given XML and I do not know why?

By default XStream is written for persistence i.e. it will read the XML it can write. If you have to transform a given XML into an object graph, you should go the other way round. Use XStream to transfer your objects into XML. If the written XML matches your schema, XStream is also able to read it. This way is much easier, since you can spot the differences in the XML much more easy than to interpret the exceptions XStream will throw if it cannot match the XML into your objects.

My parser claims the &#x0; character to be invalid, but it was written with XStream!

Your parser is basically right! A character of value 0 is not valid as part of XML according the XML specification (see version 1.0 or 1.1), neither directly nor as character entity nor within CDATA. But not every parser respects this part of the specification (e.g. Xpp3 will ignore it and read character entities). If you expect such characters in your strings and you do not use the Xpp3 parser, you should consider to use a converter that writes the string as byte array in Base64 code. As alternative you may force the PrettyPrintWriter or derived writers to be XML 1.0 or 1.1. compliant, i.e. in this mode a Stream Exception is thrown.

My parser claims a control character to be invalid, but it was written with XStream!

Your parser is probably right! Control characters are only valid as part of XML 1.1. You should add an XML header declaring this version or use a parser that does not care about this part of the specification (e.g. Xpp3 parser).

JSON specifics

Why are there two JSON driver implementations?

As always, first for historical reasons! Main difference is that the JettisonMappedXmlDriver is a thin wrapper around Jettison in combination with the StaXDriver, while the JsonHierarchicalStreamDriver uses an own more flexible implementation, but can only be used to generate JSON, deserialization is not implemented.

Why is it not possible to deserialize a JSON string starting with an array?

XStream's implementation to deserialize JSON is based on Jettison and StaX. Jettison implements a XMLStreamReader of StaX and transforms the processed JSON virtually into XML first. However, if the JSON string starts with an array it is not possible for Jettison to create a valid root element, since it has no name.

XStream fails to unmarshal my JSON string and I do not know why?

Deserialization of JSON is currently done by Jettison, that transforms the JSON string into a StaX stream. XStream itself does nothing know about the JSON format here. If your JSON string reaches some kind of complexity and you do not know how to design your Java objects and configure XStream to match those, you should have a look at the intermediate XML that is processed by XStream in the end. This might help to identify the problematic spots. Also consider then marshalling your Java objects into XML first. You can use following code to generate the XML:

final String json = "{string:\"foo\"}";
final HierarchicalStreamDriver driver = new JettisonMappedXmlDriver();
final StringReader reader = new StringReader(json);
final HierarchicalStreamReader hsr = driver.createReader(reader);
final StringWriter writer = new StringWriter();
new HierarchicalStreamCopier().copy(hsr, new PrettyPrintWriter(writer));
writer.close();
System.out.println(writer.toString());

What limitations has XStream's JSON support?

JSON represents a very simple data model for easy data transfer. Especially it has no equivalent for XML attributes. Those are written with a leading "@" character, but this is not always possible without violating the syntax (e.g. for array types). Those may silently dropped (and makes it therefore difficult to implement deserialization). Another issue are references in the serialized object graph, since JSON has no possibility to express such a construct. You should therefore always set the NO_REFERENCES mode of XStream.

Why are there invalid characters in my JSON representation?

The JSON spec requires any JSON string to be in UTF-8 encoding. However, XStream ensures this only if you provide an InputStream or an OutputStream. If you provide a Reader or Writer you have to ensure this requirement on your own.

Comparison to other products

How does XStream compare to java.beans.XMLEncoder?

XStream is designed for serializing objects using internal fields, whereas XMLEncoder is designed for serializing JavaBeans using public API methods (typically in the form of getXXX(), setXXX(), addXXX() and removeXXX() methods.

How does XStream compare to JAXB (Java API for XML Binding)?

JAXB is a Java binding tool. It generates Java code from a schema and you are able to transform from those classes into XML matching the processed schema and back. Note, that you cannot use your own objects, you have to use what is generated.

Scalability

Is XStream thread safe?

Yes. Once the XStream instance has been created and configured, it may be shared across multiple threads allowing objects to be serialized/deserialized concurrently (unless you enable the auto.detection and processing of annotations).

Uses of XStream

Is XStream a data binding tool?

No. It is a serialization tool.

Can XStream generate classes from XSD?

No. For this kind of work a data binding tool such as XMLBeans is appropriate.

Why is there no SaxReader?

XStream works on a stream-based parser model, while SAX is event-based. The steam based model implies, that the caller consumes the individual tokens from the XML parser on demand, while in an event-based model the parser controls the application flow on its own and will use callbacks to support client processing. The different architecture makes it therefore impossible for XStream to use an event-driven XML parser.