Java Architecture for XML Binding (JAXB) FAQs
Index
JAXB 2.0
- Which version of Java SE does JAXB 2.0 require?
- Does JAXB 2.0 contain JAXB 1.0?
- Which version of JAXB 1.0.x is bundled with JAXB 2.0?
- Can the JAXB 2.0 xjc compiler generate JAXB 1.0 code?
- Can I run my existing JAXB 1.0.x applications on the JAXB 2.0 runtime?
- What if I want to port my JAXB 1.0.x application to JAXB 2.0?
- What are the licensing terms for JAXB 2.0?
Miscellaneous
- What happened to the original FAQ?
- Can I redistribute JAXB with my application? What are the licensing terms?
- Are the JAXB runtime API's thread safe?
- Why can't I cast the unmarshalled object into the generated type?
- Which jar files do I need to distribute with my application that uses the JAXB RI?
- How can I cause the Marshaller to generate CDATA blocks?
- Can I access <xs:any/>?
- How can I deploy my JAXB applications on SJS AS8.x?
- How do I use JAXB with Java WebStart?
- How do I find out which version of the JAXB RI I'm using?
Q. Which version of Java SE does JAXB 2.0 require?
A. Java SE 6 (since JAXB 2.2.5 version). JAXB 2.0 relies heavily on the new language features available in Java SE 6.
Q. Does JAXB 2.0 contain JAXB 1.0?
A. Yes. The JAXB 2.0 release contains the necessary compile-time and runtime libraries for JAXB 1.0.x applications
Q. Can the JAXB 2.0 xjc compiler generate JAXB 1.0 code?
A. Yes. See the xjc instructions for a description of the -source switch.
Q. Can I run my existing JAXB 1.0.x applications on the JAXB 2.0 runtime?
A. Yes. You just need to make sure that you deploy the jaxb1-impl.jar with your application.
Q. What if I want to port my JAXB 1.0.x application to JAXB 2.0?
A. You need to recompile your schema with the newer JAXB 2.0 xjc and modify your application code to work with the new bindings.
Q. Are the JAXB runtime API's thread safe?
A. The JAXB Specification currently does not address the thread safety of any of the runtime classes. In the case of the Oracle JAXB RI, the JAXBContext class is thread safe, but the Marshaller, Unmarshaller, and Validator classes are not thread safe.
For example, suppose you have a multi-thread server application that processes incoming XML documents by JAXB. In this case, for the best performance you should have just one instance of JAXBContext in your whole application like this:
class MyServlet extends HttpServlet {
static final JAXBContext context = initContext();
private static JAXBContext initContext() {
return JAXBContext.newInstance("....",MyServlet.class.getClassLoader());
}
And each time you need to unmarshal/marshal/validate a document. Just create a new Unmarshaller/Marshaller/Validator from this context, like this:
public void doGet( HttpServletRequest req, HttpServletResponse ) {
Unmarshaller u = context.createUnmarshaller();
u.unmarshal(...);
}
This is the simplest safe way to use the JAXB RI from multi-threaded applications.
If you really care about the performance, and/or your application is going to read a lot of small documents, then creating Unmarshaller could be relatively an expensive operation. In that case, consider pooling Unmarshaller objects. Different threads may reuse one Unmarshaller instance, as long as you don't use one instance from two threads at the same time.
Q. Why can't I cast the unmarshalled object into the generated type.
A. When you invoke JAXBContext.newInstance("aaa.bbb.ccc")
, it tries to load classes and resources using the same
classloader used to load the JAXBContext class
itself. This classloader may be different from the classloader
which was used to load your application (see the picture). In
this case, you'll see the above error. This problem is often
seen with application servers, J2EE containers, Ant, JUnit, and
other applications that use sophisticated class loading
mechanisms.
With some applications, things get even more complicated when the
JAXB-generated code can be loaded by either classloader. In this
case, JAXBContext.newInstance("aaa.bbb.ccc") will work
but the JVM ends up loading two copies of the generated classes for
each class loader. As a result, unmarshalling works but an attempt
to cast the returned object into the expected type will fail, even
though its getClass().getName() returns the expected
name.
The solution for both situations is to pass your curent class loader like this:
JAXBContext.newInstance( "aaa.bbb.ccc", this.getClass().getClassLoader() );
In general, if you are writing code that uses JAXB, it is always better to explicitly pass in a class loader, so that your code will work no matter where it is deployed.
Q. Which jar files do I need to distribute with my application that uses the JAXB RI?
A. For the latest JAXB 2.0:
- $JAXB_HOME/lib/jaxb-api.jar - should be in endorsed folder. Be aware that <java-home> refers to the the top-level directory of the Java SE Runtime Environment or the jre directory in the JDK.
- $JAXB_HOME/lib/jaxb-impl.jar
- $JAXB_HOME/lib/jaxb-core.jar
- jaxb1-impl.jar (Only required when deploying JAXB 1.0 apps and can be downloaded from maven).
Q. How can I cause the Marshaller to generate CDATA blocks?
A. This functionality is not available from JAXB directly, but you can configure an Apache Xerces-J XMLSerializer to produce CDATA blocks. Please review the JaxbCDATASample.java sample app for more detail.
Q. Can I access <xs:any/> as a DOM node?
A. In JAXB 2.0, <xs:any/> is handled correctly without any customization.
- If it's "strict", it will map to Object or List<Object and when you unmarshal documents, you'll get objects that map to elements (such as JAXBElements or classes that are annotated with XmlRootElement.)
- If it's "skip", it will map to org.w3c.dom.Element or List<Element and when you unmarshal documents, you'll get DOM elements.
- If it's "lax", it will map to the same as with "strict", and when you unmarshal documents, you'll get either (i)JAXBElements, (ii) classes that are annotated with XmlRootElement, and/or (iii) DOM elements.
Q. How do I use JAXB with Java WebStart?
A. Please refer to Fabien Tison's post on the JAXB mailing list.
You can also search the mailing list for other Java WebStart messages.
Q. How do I find out which version of the JAXB RI I'm using?
A. Run the following command
$ java -jar jaxb-xjc.jar -version
Alternatively, each JAXB jar has version information in its
META-INF/MANIFEST.MF, such as this:
Build-Version: JAXB RI 2.2.8-SNAPSHOT
