May 3, 2011

Specifying EclipseLink MOXy as Your JAXB Provider

To specify EclipseLink MOXy as the JAXB provider you need to put a jaxb.properties file in one of the packages for your domain classes, that is passed in to bootstrap the JAXBContext.

Java Model

Our Java model will consist of the following two classes that reference each other.  This is important because when you bootstrap a JAXBContext on a class, the classes that it references are also processed.   I have also put these classes in separate packages so that we can examine the impact of where you put the jaxb.properties file.

example.foo.Foo

package example.foo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import example.bar.Bar;

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private Bar bar;

}

example.bar.Bar

package example.bar;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import example.foo.Foo;

@XmlAccessorType(XmlAccessType.FIELD)
public class Bar {

    private Foo foo;

}

example/foo/jaxb.properties

To specify that the MOXy implementation of JAXB should be used we will put a jaxb.properties file with the following entry in the same package as the Foo class.

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Demo Code

Since the Foo and Bar classes reference each other, ultimately the JAXBContext will contain metadata about both of them, but based on how we create the JAXBContext the provider can be different.  In order for the jaxb.properties file to be processed it must be in the same package as at least one of the domain classes specified when bootstrapping the JAXBContext.

package example;

import javax.xml.bind.JAXBContext;
import example.foo.Foo;
import example.bar.Bar;

public class Demo {

    public static void main(String[] args) throws Exception{
        System.out.println(JAXBContext.newInstance(Foo.class).getClass());
        System.out.println(JAXBContext.newInstance(Bar.class).getClass());
        System.out.println(JAXBContext.newInstance(Foo.class, Bar.class).getClass());
    }

}

Running the above code will produce:

class org.eclipse.persistence.jaxb.JAXBContext
class com.sun.xml.bind.v2.runtime.JAXBContextImpl
class org.eclipse.persistence.jaxb.JAXBContext

You will notice that when we bootstrapped the JAXBContext on the Bar class we did not MOXy as our JAXB provider. This is because none of the classes we passed to create the JAXBContext were from a package that contained a jaxb.properties file.  This is the intended behaviour, and something to be aware of when specifying a JAXB provider.


Further Reading

Once you are able to configure EclipseLink MOXy as your JAXB provider you can take advantage of its many extensions:

14 comments:

  1. Hi Blaise,

    If i already have my model classes inside a jar file, where should i put the jaxb.properties?

    Thanks

    ReplyDelete
  2. Hi Frederick,

    If you can't modify the jar with the model classes, then you could create a second jar that contained that package with the jaxb.properties file.

    -Blaise

    ReplyDelete
  3. Hi Blaise,

    I want to know just by using jaxb jar and xmlseealso annotation (specifying my subclasses),
    can i achieve polymorphism while marshalling & unmarshalling ??.

    For the other alternatives you had suggested in past,

    1.I can't go for Jee6 reference impln (the one you mentioned in your answer raised at stackoverflow).
    2.I may require to go through some approval to use elcipse your link moxy impln.

    Thats why i want to know, possibility of polymorphism using jaxb jar & xmlseealso annotation. ?

    - ragav K

    ReplyDelete
  4. Hi Rajav,

    All JAXB implementations support polymorphism, as you've pointed out I've covered different styles in previous posts:
    - JAXB and Inheritance - Using the xsi:type Attribute
    - JAXB and Inheritance - Using Substitution Groups
    - Ignoring Inheritance with @XmlTransient

    And even some EclipseLink JAXB (MOXy) specific extensions:
    - JAXB and Inheritance - MOXy Extension @XmlDescriminatorNode/@XmlDescrimintatorValue

    The @XmlSeeAlso annotation is really just a convenience mechanism for having the subclasses included when the JAXBContext is created without having to specify them directly when creating the JAXBContext.

    What issue are you hitting? Are you using the JAXB implementation included in Java SE 6?

    -Blaise

    ReplyDelete
  5. I'm using Eclipse Indigo with EclipseLink (both the JPA and MOXy for the JAXB provider). I have an EAR project with a Utility project containing all the beans. I am getting an error "Project is missing a jaxb.properties file specifying the EclipseLink JAXB context factory". My jaxb.properties file is clearly there. Any ideas?

    ReplyDelete
  6. Hi Keith,

    Where do you have your jaxb.properties file? It needs to be in the same package as the domain classes you are creating the JAXBContext on. In the following post I outline what a sample WAR might look like:
    - Creating a RESTful Web Service - Part 4/5

    Is Eclipse Indigo giving you the error/waring,
    "Project is missing a jaxb.properties file specifying the EclipseLink JAXB context factory"?

    -Blaise

    ReplyDelete
  7. thanks for the demo codes. I appreciate the great help it brought to me.

    ReplyDelete
  8. I would just like to ask again keith's question, where do you have your jaxb.properties?... I just get the right answer. I visit the link keith posted but it just made me confused. Can you answer it,\.

    ReplyDelete
  9. I am so pleased with your help. Finally my looping error in xml vanished with the jaxb.properties file. Never thought that I am not already using the moxy implementation. Just wanted to say Thank You!

    ReplyDelete
  10. "You will notice that when we bootstrapped the JAXBContext on the Bar class we did not MOXy as our JAXB provider."

    Is this going to be a problem during marshalling/unmarshalling process? What is the solution to this? Do we have to create the jaxb.properties in each of the packages?

    ReplyDelete
    Replies
    1. As long as the jaxb.properties file is in the same package as one of the classes used to bootstrap the JAXBContext you are fine. I have updated the post to make it more clear.

      -Blaise

      Delete
  11. Thank You a lot! This article helped me a lot!

    ReplyDelete
  12. You are the best!! Thanks for this example!!!

    ReplyDelete