Over a million developers have joined DZone.

JavaBeans to XML, With No Libraries

· Java Zone

Discover how AppDynamics steps in to upgrade your performance game and prevent your enterprise from these top 10 Java performance problems, brought to you in partnership with AppDynamics.

Converting JavaBeans to XML and viceversa is quite a common task, and there are tons of libraries around for this purpose. But I always like to use what is already available in the JRE, avoiding dependencies as much as possible. In the past I and Simone developed a rest API using the JSR57 serialization, that was already available in the Java 5. But Java 6 included JAXB in the standard libraries, which is more modern and flexible, and gives you a better control over the XML translation process.

Here I want to provide a couple of simple examples to show how those two APIs work.

Suppose we have some java beans "the model" as per the following source:

public class Book implements Serializable {
String title;
String author;
Price price;
public Book() {} //default constructor is mandatory for JavaBeans

public Book(String title, String author, Price price) {
this.title= title;
this.author = author;
this.price = price;

//... imagine the getter and setters boilerplate code here ...

public String toString() {
return title + " by " + author + ", " + price;


public class Price implements Serializable {
Double amount;
Currency currency;

public Price() {} // default constructor, as JavaBeans mandate...

public Price(Double amount, Currency currency) {
this.amount = amount;
this.currency = currency;

//... imagine the getter and setters boilerplate code here ...

public String toString() {
DecimalFormat fmt = new DecimalFormat("0.00");
return fmt.format(amount) + currency;
Two simple JavaBeans, a classic example: one models a book, with title, author and price. And the price is composed by the amount and the currency. The Currency class with its hidden partner CurrencyData class are a funny couple in the JDK; if you look at the code you may find it quite amusing; I suggest to never use that. By the way, it is a good example here, because that class other than having such source code, doesn't have a public default constructor, and makes the XML marshaling fail. So it makes a good example for a not so trivial XML serialization.

The following code samples will instantiate a Book object, as per above class definitions, then transform that to an XML String, and after the XML String will be used to reconstruct another instance of the Book object.

JSR57 Serializer. Also known as "XMLDecoder/XMLEncoder"

Let's start with the JSR57 Serializer.

public class Jsr57Spike {
public static void main(String[] args) throws Exception {
Book book = new Book("Carrie", "Stephen King", new Price(17.25,

String xml = encode(book);

Object o = decode(xml);
System.out.println("decoded object: " + o);

private static String encode(Book book) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder(out);


return out.toString();

private static void fixCurrency(XMLEncoder encoder) {
new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance,
Encoder out) {
return new Expression(Currency.class, "getInstance",
new Object[] { oldInstance.toString() });

private static Object decode(String xml)
throws UnsupportedEncodingException {
XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(xml
return decoder.readObject();

As you can see, I had to write a special handler to deal with the java.util.Currency class (lines 25..33), the PersistencyDelegate for the Currency class has to be set on the encoder before usage. If you don't do it, it will not throw any exception, but the decoder will be unable to deserialize the XML as it will fail to instantiate the Currency class. It will not throw any exception, it will just print on System.error some weird stuff like:

java.lang.InstantiationException: java.util.Currency
Continuing ...
java.lang.RuntimeException: failed to evaluate: <unbound>=Class.new();
Continuing ...

And the decoded object will miss the currency instances. You can easily try that commenting the line number 17, where the "fix" is applied.

With the fix in place, everything should go fine and produce the following output:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_20" class="java.beans.XMLDecoder">
<object class="it.newinstance.xml.spike.model.Book">
<void property="author">
<string>Stephen King</string>
<void property="price">
<object class="it.newinstance.xml.spike.model.Price">
<void property="amount">
<void property="currency">
<object class="java.util.Currency" method="getInstance">
<void property="title">

decoded object: Carrie by Stephen King, 17.25CHF

We may find that the above XML representation is possibly too verbose and too Java-centric. So we may look forward to Jaxb...

But it's nice to notice here that in this case I didn't have to touch the model (Book and Price class) as the XMLDecoder/Encoder are really not intrusive and may be suitable for JavaBeans from which we do not have the source code or we can't easily change.

JAXB: Java Architecture for XML Binding

Following code does again the same stuff: from a JavaBean to XML and the way back.

public class JaxbSpike {
private static class XMLBook extends Book {
public XMLBook() {} // default constructor is mandated by JavaBeans spec

public XMLBook(String title, String author, Price price) {
super(title, author, price);

public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(XMLBook.class);
Book book = new XMLBook("Carrie", "Stephen King", new Price(17.25,

String xml = marshall(jc, book);

Book unmashalledBook = unmarshall(jc, xml);
System.out.println("Last book I read: " + unmashalledBook);

private static Book unmarshall(JAXBContext jc, String xml)
throws JAXBException {
Unmarshaller u = jc.createUnmarshaller();
return (Book) u.unmarshal(new StringReader(xml));

private static String marshall(JAXBContext jc, Book book)
throws JAXBException, PropertyException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(book, out);
return out.toString();

Jaxb requires that the object which represents the XML root has to be annotated with the @XmlRootElement. As I don't like to change my model just to transform it, I preferred in this example to subclass Book and apply the XML serialization to the inner class XMLBook where I can add the annotation without any problem.

At line 34 I set the JAXB_FORMATTED_OUTPUT property to true to produce a formatted XML. This is helpful for human reading, but it is good to have the ability to produce an XML on a single line to optimize the fruition by machines.

The rest of the code is quite self explanatory.

Here, I didn't had to add any handler for the Currency class in the marshaller/unmarshaller code... But I had to declare the converter with an annotation applied to the package. To annotate the package containing the model classes you need to create a special file named "package-info.java" with following source:

package it.newinstance.xml.spike.model;
import java.util.Currency;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

The marshaller/unmarshaller will check the annotations applied to the classes, the fields, and the packages, and apply the specified rules. JAXB has a rich set of annotations that can be applied to your JavaBeans and the packages themselves. The problem is that annotations are, under all aspects, interface elements. Annotating a class means introducing dependencies and changing the interfaces of your domain model. Also take in mind that sometime you just don't own the source code of the JavaBeans you want to serialize or you cannot change them. Subclassing may help, as I showed in the above example, introducing the XMLBook inner class, but it may be not enough. Further investigation of the JAXB API may show solutions to this issue, but at the moment, I don't know...

Then I had also to create a very simple CurrencyAdapter class, which will be used by JAXB to handle the translations Java <-> XML

public class CurrencyAdapter extends XmlAdapter<String, Currency>{

public String marshal(Currency v) throws Exception {
return v.toString();

public Currency unmarshal(String v) throws Exception {
return Currency.getInstance(v);

If you don't set up the CurrencyAdapter, the Exception that you will get is the following:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
  java.util.Currency does not have a no-arg default constructor.
	this problem is related to the following location:
		at java.util.Currency
		at public java.util.Currency it.newinstance.xml.spike.model.Price.getCurrency()
		at it.newinstance.xml.spike.model.Price
		at public it.newinstance.xml.spike.model.Price it.newinstance.xml.spike.model.Book.getPrice()
		at it.newinstance.xml.spike.model.Book
		at it.newinstance.xml.spike.jaxb.JaxbSpike$XMLBook

	at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
	at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
	at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
	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 javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
	at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
	at it.newinstance.xml.spike.jaxb.JaxbSpike.main(JaxbSpike.java:32)

I have to say that the exception is very descriptive of the problem. JAXB, for the little I had the chance to see, is a very well made API.

So, now that we have all in place, let's see what's the output of our JaxbSpike:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<author>Stephen King</author>

Last book I read: Carrie by Stephen King, 17.25EUR

For sure a better, simpler and non-Java-centric representation of the Book object, if we compare this with the output given using the XMLEncoder.

But, we have to notice that we have introduced the annotation on the package, so we changed the original domain. It is possible that, learning better the JAXB APIs, this change may be avoided, but I am really not confident in that. For sure JAXB is the best choice when you have some flexibility in changing the code of your JavaBeans.

Want to try by yourself?

Here you find the source code: JavaBeansToXml.tar.gz

Good luck!

P.S. This is all I know about JAXB and JSR57 XML serialization; if you have a specific problem it's better to refer to some community forum. But feel free to leave a comment, I will be happy to help if I know the answer.

From http://en.newinstance.it/2010/08/05/javabeans-to-xml-with-no-libraries/

The Java Zone is brought to you in partnership with AppDynamics. AppDynamics helps you gain the fundamentals behind application performance, and implement best practices so you can proactively analyze and act on performance problems as they arise, and more specifically with your Java applications. Start a Free Trial.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}