Marshall JAXB Elements Without Prior Declaration of Their Type

Java Architecture for XML Binding (JAXB) is an API for access of XML documents from applications written in the Java programming language. It’s convenient to use as it usually follows this pattern:

  1. Create JAXBContext
  2. Create Marshaller/Unmarshaller
  3. Marshal/Unmarshal the code

The following are examples that marshal:

and unmarshal XML document to object:

The marshalled XML looks like this:

The actual model is this:

As you can see the JAXBContext is initialized with the classes that take part in the marshall/unmarshall process (in this case the Project class has a reference to the Task class and that’s why there is no need to pass all classes to the JAXBContext). This means that those classes should be known beforehand. However often this is not the case. There are cases when the contained elements are known only at runtime. One such example is a Task Runner – an application that can run tasks and the tasks with their execution order and parameters are contained in single XML file (sounds familiar? Yep, Ant is what comes to mind). Consider the following example:

It contains several elements that have different names – tstamp, mkdir, delete – however they are all of the same type. They are all Tasks. And because such an application is extensible (users can add arbitrary Tasks) by plugins the Tasks are not known beforehand.

Let’s start with the model

Minor changes can be spotted. First of all Task is an abstract class so the actual implementors are not referenced. The other thing is the @XmlElementRef annotation. This annotation dynamically associates an XML element name with the JavaBean property. When used the XML element name is derived from the instance of the type of the JavaBean property at runtime.

This is the Java code defining the Tasks

There are two ways to marshal those objects. First add jaxb.index file to the package containing the JAXB annotated classes and list them. The second way is to provide ObjectFactory in the package containing the JAXB annotated classes.

 

Source: ObjectFactory.java
Here is an app that instantiates custom tasks and marshals them

Source: Application.java
As you can see in this case the JAXBContext is created by specifying the package names containing the JAXB annotated classes.

Full source code

 

Resources:
https://jaxb.java.net/nonav/2.2.4/docs/api/javax/xml/bind/annotation/XmlElementRef.html
https://jaxb.java.net/nonav/2.2.4/docs/api/javax/xml/bind/annotation/XmlElementDecl.html

Leave a Reply

Your email address will not be published. Required fields are marked *