1.3 or later.
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.
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.
Feature | Pure Java | Enhanced Mode |
---|---|---|
Public classes | Yes | Yes |
Non public classes | No | Yes |
Static inner classes | Yes | Yes |
Non-static inner classes | No | Yes |
Anonymous inner classes | No | Yes |
With default constructor | Yes | Yes |
Without default constructor | No | Yes |
Private fields | Yes | Yes |
Final fields | Yes >= JDK 1.5 | Yes |
Yes. Let us know which JVM you would like supported.
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.
This depends on the mode XStream is running in. Refer to the SecurityManagerTest for details.
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; } };
Make it transient
or specify it with XStream.omitField()
XStream uses the same mechanism as the JDK serialization. Example:
class ThreadAwareComponent { private transient ThreadLocal component; // ... private Object readResolve() { component = new ThreadLocal(); return this; } }
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; } }
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.
No.
Yes.
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)));
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.
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.
For more advanced class migrations, you may
Future versions of XStream will include features to make these type of migrations easier.
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.
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.
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).
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.
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 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.
Yes. Once the XStream instance has been created and configured, it may be shared across multiple threads allowing objects to be serialized/deserialized concurrently.
No. It is a serialization tool.
No. For this kind of work a data binding tool such as XMLBeans is appropriate.
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.