Using custom ObjectFactory with JAXB: is there an established "go to" pattern?

7.2k views Asked by At

I understand that the ObjectFactory is often automatically generated when working with JAXB as one might define schema and XML first. However, this is not the way I can approach the project.

I have existing code which needs to be annotated and extended to use JAXB to then use it in conjunction with a REST service. I have only a handful of classes and annotated them already. As far as I understood the documentation (I am new to JAXB), I need an implementation of ObjectFactory either by package for automatic invocation on package level, or a multitude of implementations when they are referred to directly rather than referred to by package context.

I am a bit unsure what the best approach would be. If I were to use one implementation per package then the manager would be rather abstract, instantiating many classes. However, I am not sure this is the "right" way to do it. I would personally opt to separate the concerns for instantiation into separate instances of the ObjectFactory, i.e., have one factory per class. Hence, I would implement something similar to the Data Access Object pattern.

My engineering background tells me that separation of concerns and opting for extension over modification would be a better choice. Hence, my intuition tells me that the monolithic ObjectFactory is only used when produced as a result of the approach starting from XML rather than code. Yet I don't have enough experience to make an informed choice.

I would like to ask you not only for your experience with the technology and recommendation (which would be to opinion based) but also whether this approach will introduce any risks that I am missing as well as technical limitations regarding JAXB that I might run into if I pursue my course of action. Thank you!

1

There are 1 answers

4
bdoughan On

Creating a JAXBContext on a Package Name

When you create a JAXBContext on a package name:

JAXBContext jc = JAXBContext.newInstance("com.example.foo");

The JAXB implementation doesn't do package scanning, so it needs to find something in that package from which it can derive the rest of the model. This can either be:

  1. An ObjectFactory class with create methods that reference the domain model. Bootstrapping of this is best when your model is generated from an XML Schema
  2. A jaxb.index file, which is just a carriage return separated list of short class names (not package qualified) of the classes you want to bootstrap the JAXBContext on. This does not need to be the whole list as JAXB will pull in referenced classes. It is best to use this approach when you start from Java classe.

What ObjectFactory is Used For

As far as metadata is concerned the ObjectFactory has:

  1. create methods from the signature of which the domain model can be determined (if you bootstrapped on the ObjectFactory alone.
  2. @XmlElementDecl annotations. An @XmlElementDecl annotation is like an @XmlRootElement annotation but used in the cased for top-level elements that have a named type (see: http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html).

What ObjectFactory is Not Used For

The ObjectFactory is not used during the umarshal operation to create instances of the domain classes. For more information see the question linked below:

Creating a JAXBContext in a JAX-RS Environment

You mentioned you are doing REST. If you are using a JAX-RS implementation for this (such as Jersey) then I would suggest using a ContextResolver to create your JAXBContext. Below is an example from my blog. In that example an extension in the MOXy JAXB impl is used to provide the metadata, but you can create that JAXBContext anyway you want to.