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

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. 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 JavaBean mode as alternative to 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;
    }
};

Serialization

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

Make it transient or specify it with XStream.omitField()

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 problem as above. XStream uses the same mechanism as the JDK serialization. When using 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 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)));

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.

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 pointers that should be cleaned by the garbage collector when the types are reloaded.

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 uses by default the Xpp3 parser which does ignore the declaration, so you have to provide a Reader with the appropriate encoding yourself if you do not want to read the XML in the default encoding of the current local or you must use a HierarchicalStreamDriver with an XML parser that respects the XML declaration.

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.

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.

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.

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.

Development

Why is the XStream source stored in a Subversion repository? What's wrong with CVS?

Subversion is a compelling replacement for CVS. It has been developed building on the experience of CVS and overcomes many of the limitations of CVS while preserving the same ease of use. Among, its advantages, Subversion does not requires connection to the Internet for commands like add, remove, rename, diff and revert. Moreover, operations are truly atomic and directories are treated like files, ie have associated metadata.