views:

13

answers:

1

Hi,

I have multiple plug-ins in my RCP-based project. I want to be able to define @XMLElements in one plug-in that can then be marshaled / un-marshaled from the core plugin. To do so, I report the classes that are serializable as soon as the plug-in is loaded. However, dynamically adding classes seems to be not supported by the JAXBContext. I implemented a work-around by holding all classes in a list and creating a new JAXBContext every time some new classes are reported based on that list, but this solution is not really nice.

Is there a better way to do that?

A: 

You definitely can not add classes dynamically to a JAXBContext. This has to do with maintaining the thread safety of JAXBContext.

I have recently posted an example on my blog explaining how to leverage the @XmlAnyElement annotation to generate a generic message that could have different payloads:

Root Object

The root element for the body property will be controlled by that objects @XmlRootElement.

package message;   

import javax.xml.bind.annotation.*;   

@XmlRootElement@XmlAccessorType(XmlAccessType.FIELD) 
public class Message {
    @XmlAttribute
    private String to;       

    @XmlAttribute    
    private String from;       

    @XmlAnyElement    
    private Object body;   
}

Creating the JAXBContext

Instead of creating the JAXBContext on an array of classes, the JAXBContext could be created on a context path:

JAXBContext.newInstance("message:customer:product"); 

This context path includes 3 package names seperated by the colon ':' character. In each of these packages we need to include a file named jaxb.index with a list of files. Below is an example of the jaxb.index file in the customer package:

Address
Customer 

When we want to add a model to represent orders to our framework we would extend our JAXBContext creation to like (this String could be passed in as a variable):

JAXBContext.newInstance("message:customer:product:order"); 
Blaise Doughan