XStream is nearing a release
XStream is a simple object -> xml -> object serialization tool. There are many other tools that do similar things out there. Here are some of the features that distinguish it from the others:
* Very fast.
* Requires no custom mappings to be created.
* Can serialize objects that have private fields and non-default constructors.
* Handles arbitary objects and collections.
* Produces very clean XML; the kind a human would write.
* Does not duplicate any information in the XML that can be obtained via reflection.
* Decoupled from XML implementations. Use it with DOM, JDOM, DOM4J, or even non-XML streams (such as custom configuration objects, YAML or properties files).
* Open source, BSD license.
Here’s an example chunk of XML produced by XStream:
Joe Walnes 123 1234-456 123 9999-999
Out of everything else out there, it looks very similiar to commons-betwixt. What are your thoughts on how it compares?
commons-betwixt is quite unusable in some situations. Actually I think it can’t be used for anything but some very trivial cases. I tried to use it for parsing a not too complicated XML document but it didn’t work — however, it could be done with castor easilly.
Betwixt has been designed for JavaBeans, whereas XStream has been designed for Objects.
Betwixt serializes properties, XStream serializes fields. The advantage XStream has here is that your objects do not need to expose their private state (violating encapsulation).
Betwixt requires a default constructor, XStream ignores constructors.
Hey Joe,
Nice piece of work! I got a few questions. First, what xml parser does this rely on? Or do you have your own simple object to xml (that is easy enough) and xml to object (a bit harder) code in place?
How fast is it compared to using RMI and serializable? Do you require objects implement Serializable to serialize them to xml and back?
Lastly, what about using compression? Can you make that an option so that it zips the stream either as it converts to xml on the fly, or after the xml stream is created in memory run it through a zip stream or something? Maybe even gzip (not sure what the difference is actually)?
Thanks.
> Nice piece of work! I got a few questions. First, what xml parser does this rely on?
The XML parser has been abstracted from the code, allowing you to use any. It is bundled with W3C DOM, JAXP and DOM4J implementations, although you can easily plug it into another api (such as Electric, JDOM, XOM, etc).
> Or do you have your own simple object to xml (that is easy enough) and xml to object (a bit harder) code in place?
Yeah, that’s what it does.
> How fast is it compared to using RMI and serializable?
Faster! I’ve tested :)
> Do you require objects implement Serializable to serialize them to xml and back?
Nope. Although you may get weird results if you try to serialize certain types of objects (such as File or InputStream).
> Lastly, what about using compression? Can you make that an option so that it zips the stream either as it converts to xml on the fly, or after the xml stream is created in memory run it through a zip stream or something? Maybe even gzip (not sure what the difference is actually)?
Sure you can. Because you can implement your own xml reader/writer implementation you can do whatever you want. You can even store it in a more compact form than XML such as YAML.
cheers
-joe
Hi Joe
How does it get and set private fields. Is this documented somewhere? I was reading an article about native serialization in ACM and it implied that the XStream classes were in the java.io package. Is that so that they can access the package-protected members there? Or does it work by suppressing reflection access exceptions so that you require the necessary security permission?
Thanks
John
It uses plain old reflection to get and set private fields, using the Field.setAccessible() property. This is possible providing you are not using a locked down security manager, which most people are not. It does not need to reside in the java.io package.
Which article were you reading? It sounds like it’s talking about something else.
Hey Joe.
Very cool!
But of course, I do have a question.
Is there a way to write out the XML so that an attribute in an object is put in the xml as a value to an element rather than its own element?
For example, if I have this class:
public class Dog
{
private String name;
private String breed;
public Dog(){}
// Get and set methods
}
and I want to create an xml like this:
Bloodhound
instead of this:
Fido
Bloodhound
How do I do that?
And of course, I would want to be able to unmarshall an XML file with values to elements in the same manner to create java objects.
Any help would be appreciated.
Thanks!
Eric,
XStream is intended as a transparent serialization library rather than a mapping framework. If you need flexible control of how an object is stored as XML this would require mappings to be specified. XStream doesn’t currently have a mechanism to specify mappings like this.
If you want fine grained control of the resulting XML, I would recommend a product that is more suited to the job, such as Castor.
Saying that, it is possible to do what you are requesting with XStream by providing a custom implementation of the Converter interface, although if you are doing this a lot it may become tedious.
Hi,
are there a way to tell xstream it *must* use a constructor (say – default?) to initialize transient members to a proper state?
Thanks, Imi.
Imi,
Yes. If you always want to use default constructors, provide an instance of PureJavaReflectionProvider in the constructor of XStream. This will always instantiate objects using the default constructor.
If you want to do this for one type of class only, I would recommend creating a custom Converter implementation instead.
Finally if you want to do it for lots (but not all ) classes, you could create your own ReflectionProvider that delegated to the PureJavaReflectionProvider or Sun14ReflectionProvider based on the type.
seems to be a great (in terms of flexible) product.
my question: is it possible to control the behaviour of xstream in a situation like:
baboo
without having a member called “amember” in “aclass” !?
most frameworks just ignore the “wrong” element whereas throwing an exception would be the desired behaviour for my use case.
oh dear. the xml in the former text should have been:
%lt;aclass%gt;
%lt;amember>baboo%lt;/amember%gt;
%lt;/aclass%gt;
sorry.
One of the request features in future releases is to be able specify your own error handling strategy, so when an unknown element is found, you could just ignore it.
However this is not yet implemented. In the mean time, it should be pretty trivial to create your own modifications to ReflectionConverter class that could do this.
XSTREAM is great – it has save me so much time and effort!
I’m having trouble making this work under Java 1.3. Do you have any examples of how to get XSTREAM functioning? I’ve tried and have run into all sorts of errors.
Thanks
Brian,
XStream is JDK 1.3 friendly, with the following constraints:
– it cannot deserialize final fields.
– it cannot deserialize objects that don’t have a default constructor.
Other than that, it works fine.
I suggest you post details of your problem to the XStream mailing list.
-Joe
Is it possible to specify the use of a custom constructor?