JAXB Architecture

This section describes the components and interactions in the JAXB processing model. After providing a general overview, this section goes into more detail about core JAXB features. The topics in this section include:

Architectural Overview

Figure 1-1 shows the components that make up a JAXB implementation.

JAXB Architectural Overview

Figure 1-1 JAXB Architectural Overview

As shown in Figure 1-1, a JAXB implementation comprises the following eight core components.

Table 1-1 Core Components in a JAXB Implementation 
XML Schema
An XML schema uses XML syntax to describe the relationships among elements, attributes and entities in an XML document. The purpose of an XML schema is to define a class of XML documents that must adhere to a particular set of structural rules and data constraints. For example, you may want to define separate schemas for chapter-oriented books, for an online purchase order system, or for a personnel database. In the context of JAXB, an XML document containing data that is constrained by an XML schema is referred to as a document instance, and the structure and data within a document instance is referred to as a content tree.
By default, the JAXB binding compiler binds Java classes and packages to a source XML schema based on rules defined in Section 5, "Binding XML Schema to Java Representations," in the JAXB Specification. In most cases, the default binding rules are sufficient to generate a robust set of schema-derived classes from a wide range of schemas. There may be times, however, when the default binding rules are not sufficient for your needs. JAXB supports customizations and overrides to the default binding rules by means of binding customizations made either inline as annotations in a source schema, or as statements in an external binding customization file that is passed to the JAXB binding compiler. Note that custom JAXB binding customizations also allow you to customize your generated JAXB classes beyond the XML-specific constraints in an XML schema to include Java-specific refinements such as class and package name mappings.
The JAXB binding compiler is the core of the JAXB processing model. Its function is to transform, or bind, a source XML schema to a set of JAXB content classes in the Java programming language. Basically, you run the JAXB binding compiler using an XML schema (optionally with custom binding declarations) as input, and the binding compiler generates Java classes that map to constraints in the source XML schema.
Implementation of javax.xml.bind
The JAXB binding framework implementation is a runtime API that provides interfaces for unmarshalling, marshalling, and validating XML content in a Java application. The binding framework comprises interfaces in the javax.xml.bind package.
These are the schema-derived classes generated by the binding JAXB compiler. The specific classes will vary depending on the input schema.
In the context of JAXB, a Java application is a client application that uses the JAXB binding framework to unmarshal XML data, validate and modify Java content objects, and marshal Java content back to XML data. Typically, the JAXB binding framework is wrapped in a larger Java application that may provide UI features, XML transformation functions, data processing, or whatever else is desired.
XML Input
XML content that is unmarshalled as input to the JAXB binding framework -- that is, an XML instance document, from which a Java representation in the form of a content tree is generated. In practice, the term "document" may not have the conventional meaning, as an XML instance document does not have to be a completely formed, selfstanding document file; it can instead take the form of streams of data passed between applications, or of sets of database fields, or of XML infosets, in which blocks of information contain just enough information to describe where they fit in the schema structure.
In JAXB, the unmarshalling process supports validation of the XML input document against the constraints defined in the source schema. This validation process is optional, however, and there may be cases in which you know by other means that an input document is valid and so you may choose for performance reasons to skip validation during unmarshalling. In any case, validation before (by means of a third-party application) or during unmarshalling is important, because it assures that an XML document generated during marshalling will also be valid with respect to the source schema. Validation is discussed more later in this chapter.
XML Output
XML content that is marshalled out to an XML document. In JAXB, marshalling involves parsing an XML content object tree and writing out an XML document that is an accurate representation of the original XML document, and is valid with respect the source schema. JAXB can marshal XML data to XML documents, SAX content handlers, and DOM nodes.

The JAXB Binding Process

Figure 1-2 shows what occurs during the JAXB binding process.

Steps in the JAXB Binding Process

Figure 1-2 Steps in the JAXB Binding Process

The general steps in the JAXB data binding process are:

  1. Generate classes. An XML schema is used as input to the JAXB binding compiler to generate JAXB classes based on that schema.
  2. Compile classes. All of the generated classes, source files, and application code must be compiled.
  3. Unmarshal. XML documents written according to the constraints in the source schema are unmarshalled by the JAXB binding framework. Note that JAXB also supports unmarshalling XML data from sources other than files/documents, such as DOM nodes, string buffers, SAX Sources, and so forth.
  4. Generate content tree. The unmarshalling process generates a content tree of data objects instantiated from the generated JAXB classes; this content tree represents the structure and content of the source XML documents.
  5. Validate (optional). The unmarshalling process optionally involves validation of the source XML documents before generating the content tree. Note that if you modify the content tree in Step 6, below, you can also use the JAXB Validate operation to validate the changes before marshalling the content back to an XML document.
  6. Process content. The client application can modify the XML data represented by the Java content tree by means of interfaces generated by the binding compiler.
  7. Marshal. The processed content tree is marshalled out to one or more XML output documents. The content may be validated before marshalling.

To summarize, using JAXB involves two discrete sets of activities:

These two steps are usually performed at separate times in two distinct phases. Typically, for example, there is an application development phase in which JAXB classes are generated and compiled, and a binding implementation is built, followed by a deployment phase in which the generated JAXB classes are used to process XML content in an ongoing "live" production setting.

Note: Unmarshalling is not the only means by which a content tree may be created. Schema-derived content classes also support the programmatic construction of content trees by direct invocation of the appropriate factory methods. Once created, a content tree may be revalidated, either in whole or in part, at any time. See Create Marshal Example for an example of using the ObjectFactory class to directly add content to a content tree.

JAXB Binding Framework

The JAXB binding framework is implemented in three Java packages:

The main package in the JAXB binding framework, javax.xml.bind, is described in more detail below.

More About javax.xml.bind

The three core functions provided by the primary binding framework package, javax.xml.bind, are marshalling, unmarshalling, and validation. The main client entry point into the binding framework is the JAXBContext class.

JAXBContext provides an abstraction for managing the XML/Java binding information necessary to implement the unmarshal, marshal and validate operations. A client application obtains new instances of this class by means of the newInstance(contextPath) method; for example:

JAXBContext jc = JAXBContext.newInstance( 
"com.acme.foo:com.acme.bar" ); 

The contextPath parameter contains a list of Java package names that contain schema-derived interfaces--specifically the interfaces generated by the JAXB binding compiler. The value of this parameter initializes the JAXBContext object to enable management of the schema-derived interfaces. To this end, the JAXB provider implementation must supply an implementation class containing a method with the following signature:

public static JAXBContext createContext( String contextPath, 
ClassLoader classLoader ) 
      throws JAXBException; 

Note: The JAXB provider implementation must generate a jaxb.properties file in each package containing schema-derived classes. This property file must contain a property named javax.xml.bind.context.factory whose value is the name of the class that implements the createContext API.

The class supplied by the provider does not have to be assignable to javax.xml.bind.JAXBContext, it simply has to provide a class that implements the createContext API. By allowing for multiple Java packages to be specified, the JAXBContext instance allows for the management of multiple schemas at one time.

More About Unmarshalling

The Unmarshaller class in the javax.xml.bind package provides the client application the ability to convert XML data into a tree of Java content objects. The unmarshal method for a schema (within a namespace) allows for any global XML element declared in the schema to be unmarshalled as the root of an instance document. The JAXBContext object allows the merging of global elements across a set of schemas (listed in the contextPath). Since each schema in the schema set can belong to distinct namespaces, the unification of schemas to an unmarshalling context should be namespace-independent. This means that a client application is able to unmarshal XML documents that are instances of any of the schemas listed in the contextPath; for example:

JAXBContext jc = JAXBContext.newInstance(
  "com.acme.foo:com.acme.bar" );

Unmarshaller u = jc.createUnmarshaller();

FooObject fooObj = 
  (FooObject)u.unmarshal( new File( "foo.xml" ) ); // ok

BarObject barObj = 
  (BarObject)u.unmarshal( new File( "bar.xml" ) ); // ok

BazObject bazObj = 
  (BazObject)u.unmarshal( new File( "baz.xml" ) ); 
  // error, "com.acme.baz" not in contextPath 

A client application may also generate Java content trees explicitly rather than unmarshalling existing XML data. To do so, the application needs to have access and knowledge about each of the schema-derived ObjectFactory classes that exist in each of Java packages contained in the contextPath. For each schema-derived Java class, there will be a static factory method that produces objects of that type. For example, assume that after compiling a schema, you have a package com.acme.foo that contains a schema-derived interface named PurchaseOrder. To create objects of that type, the client application would use the following factory method:

ObjectFactory objFactory = new ObjectFactory();

com.acme.foo.PurchaseOrder po =

Note: Because multiple ObjectFactory classes are generated when there are multiple packages on the contextPath, if you have multiple packages on the contextPath, you should use the complete package name when referencing an ObjectFactory class in one of those packages.

Once the client application has an instance of the schema-derived object, it can use the mutator methods to set content on it.

Note: The JAXB provider implementation must generate a class in each package that contains all of the necessary object factory methods for that package named ObjectFactory as well as the newInstance(javaContentInterface) method.

More About Marshalling

The Marshaller class in the javax.xml.bind package provides the client application the ability to convert a Java content tree back into XML data. There is no difference between marshalling a content tree that is created manually using the factory methods and marshalling a content tree that is the result an unmarshal operation. Clients can marshal a Java content tree back to XML data to a java.io.OutputStream or a java.io.Writer. The marshalling process can alternatively produce SAX2 event streams to a registered ContentHandler or produce a DOM Node object.

A simple example that unmarshals an XML document and then marshals it back out is a follows:

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

// unmarshal from foo.xml
Unmarshaller u = jc.createUnmarshaller();
FooObject fooObj = 
  (FooObject)u.unmarshal( new File( "foo.xml" ) );

// marshal to System.out
Marshaller m = jc.createMarshaller();
m.marshal( fooObj, System.out ); 

By default, the Marshaller uses UTF-8 encoding when generating XML data to a java.io.OutputStream or a java.io.Writer. Use the setProperty API to change the output encoding used during these marshal operations. Client applications are expected to supply a valid character encoding name as defined in the W3C XML 1.0 Recommendation (http://www.w3.org/TR/2000/REC-xml-20001006#charencoding) and supported by your Java Platform.

Client applications are not required to validate the Java content tree prior to calling one of the marshal APIs. There is also no requirement that the Java content tree be valid with respect to its original schema in order to marshal it back into XML data. Different JAXB Providers can support marshalling invalid Java content trees at varying levels, however all JAXB providers must be able to marshal a valid content tree back to XML data. A JAXB provider must throw a MarshalException when it is unable to complete the marshal operation due to invalid content. Some JAXB providers will fully allow marshalling invalid content, others will fail on the first validation error.

Table 1-2 shows the properties that the Marshaller class supports.

Table 1-2 Marshaller Properties 
Value must be a java.lang.String; the output encoding to use when marshalling the XML data. The Marshaller will use "UTF-8" by default if this property is not specified.
Value must be a java.lang.Boolean; controls whether or not the Marshaller will format the resulting XML data with line breaks and indentation. A true value for this property indicates human readable indented XML data, while a false value indicates unformatted XML data. The Marshaller defaults to false (unformatted) if this property is not specified.
Value must be a java.lang.String; allows the client application to specify an xsi:schemaLocation attribute in the generated XML data. The format of the schemaLocation attribute value is discussed in an easy to understand, non-normative form in Section 5.6 of the W3C XML Schema Part 0: Primer and specified in Section 2.6 of the W3C XML Schema Part 1: Structures.
Value must be a java.lang.String; allows the client application to specify an xsi:noNamespaceSchemaLocation attribute in the generated XML data.

More About Validation

The Validator class in the javax.xml.bind package is responsible for controlling the validation of content trees during runtime. When the unmarshalling process incorporates validation and it successfully completes without any validation errors, both the input document and the resulting content tree are guaranteed to be valid. By contrast, the marshalling process does not actually perform validation. If only validated content trees are marshalled, this guarantees that generated XML documents are always valid with respect to the source schema.

Some XML parsers, like SAX and DOM, allow schema validation to be disabled, and there are cases in which you may want to disable schema validation to improve processing speed and/or to process documents containing invalid or incomplete content. JAXB supports these processing scenarios by means of the exception handling you choose implement in your JAXB-enabled application. In general, if a JAXB implementation cannot unambiguously complete unmarshalling or marshalling, it will terminate processing with an exception.

Note: The Validator class is responsible for managing On-Demand Validation (see below). The Unmarshaller class is responsible for managing Unmarshal-Time Validation during the unmarshal operations. Although there is no formal method of enabling validation during the marshal operations, the Marshaller may detect errors, which will be reported to the ValidationEventHandler registered on it.

A JAXB client can perform two types of validation:

If the client application does not set an event handler on its Validator, Unmarshaller, or Marshaller prior to calling the validate, unmarshal, or marshal methods, then a default event handler will receive notification of any errors or warnings encountered. The default event handler will cause the current operation to halt after encountering the first error or fatal error (but will attempt to continue after receiving warnings).

There are three ways to handle events encountered during the unmarshal, validate, and marshal operations:

Validation events are handled differently, depending on how the client application is configured to process them. However, there are certain cases where a JAXB Provider indicates that it is no longer able to reliably detect and report errors. In these cases, the JAXB Provider will set the severity of the ValidationEvent to FATAL_ERROR to indicate that the unmarshal, validate, or marshal operations should be terminated. The default event handler and ValidationEventCollector utility class must terminate processing after being notified of a fatal error. Client applications that supply their own ValidationEventHandler should also terminate processing after being notified of a fatal error. If not, unexpected behavior may occur.