In my last article, I discussed a very high-level view of Web services. In this article, part one of a three-part series, I'll take an almost 180-degree turn and look at the services provided to develop and access Web services in Java. Specifically, I'll look at the so-called JAX Pack, a set of loosely-coupled APIs that provide wrappers or functionality around a specific XML feature, for the most part required to access or develop Web services from a Java application.

As we saw in my prior article, Web services need to provide a definition of their service, advertise their availablity, and then bind and provide the service at run time. Each of the JAXPack APIs either provides one of these services, or supports some feature of one of these services.

There are five APIs in the JAX collection, each addressing a different XML feature:

Each of these areas is in varying states of completeness. (The JAX Pack APIs are currently controlled by the Java Community Process and Sun Microsystems). JAXP -- the only API that has reached the accepted stage and is available for download -- is currently at version 1.1, with reference and industry implementations available, while JAXB is only at version 0.21; all other JAXP APIs are in varying stages of completeness, but all are targeted for completion by year's end.

In this article we will examine the first two JAXPack APIs -- JAXP and JAXB. A second article will look at JAXM -- the API for messaging, and a third article will cover the remaining two APIs -- JAX-RPC and JAXR.

JAXP -- Java API for XML Processing

Diagram thumbnail -- click for full-size view.

Figure 1. JAXPack and Web Applications -- click for full-size view.

Current specification status: Current Version 1.1, with industry vendor support and reference implementation.

The name of JAXP is something of a misnomer -- the Java API for XML Processing. JAXP doesn't in fact provide any processing at all, but rather provides a mechanism for returning SAX parsers and DOM documents. JAXP provides two specific services:

JAXP v1.1 supports:

DOM Core Level II
The Document Object Model (DOM) specification provides mechanisms to build and traverse an in-memory, tree-based representation of a XML document. DOM Level I provided core mechanisms for traversing a tree and adding, deleting, and updating content. DOM Level II provides support for events, namespaces, etc. DOM Level II is supported in JAXP v1.1.
SAX 2.0
The Simple API for XML (SAX) specification provides an event-based mechanism for parsing XML documents. Various interfaces can be implemented so that when a particular tag or portion of an XML document is encountered, a developer-based method is called to handle the event. SAX 2.0 went beyond the first version, providing support for name spaces and custom event filters. SAX 2.0 is supported in JAXP v1.1.
XSLT 1.0
The Extensible Stylesheet Transformation(XSLT) specification defines various scripting mechanisms to transform one XML document into another. JAXP provides mechanisms for taking either SAX parsers or DOM objects and transforming them, outputting either a DOM object or a SAX Parser. XSLT v1.0 is supported by JAXP v1.1.

Originally, each and every vendor providing a DOM implementation was required to provide its own hooks for creating org.w3c.dom.Document objects. The code snippet below shows how you might have gone about obtaining a DOM object using an earlier version of Sun's DOM implementation.

Listing 1:

00 import*;
01 import com.sun.xml.tree.*;
02 import org.w3c.dom.*;
03   public class OpenWithSun {
04      public static void main (String argv []) {
05      . . .
06      FileInputStream inStream; 
07      Document document; 
08      String xmlDocumentPath = argv[0]; 
09      try { 
10          inStream = new FileInputStream(xmlDocumentPath); 
11          document = XmlDocument.createXmlDocument(inStream,true);
12      } 
13      catch (Exception e) { 
14          System.out.println("Unexpected exception reading document!" +e); 
15          System.exit(0); 
16      } 
17      . . .
18   }
19 }

We can see on lines 01 and 11 how we needed to include Sun-specific classes, as well as use a Sun-specific mechanism to create a a DOM Document object. Sun, IBM, Oracle and others -- basically, everyone with a implementation of the org.w3c.dom classes -- all had a vendor-specific mechanism for bootstrapping a DOM document object. JAXP provides an abstract mechanism -- one that is not bound to any given implementation -- for doing the same thing.

The equivalent JAXP code would be:

Listing 2:

00 import javax.xml.parsers.*;
01 import*;
02 import org.w3c.dom.*; 
03 public class DocumentBuilderExample { 
04   public static void main(String argv []) { 
05   . . . 
06   try { 
07      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
08      DocumentBuilder builder = factory.newDocumentBuilder(); 
09      Document doc = builder.parse(new File(args[0]));
10      . . . 
12      catch (Exception e) { 
13          System.out.println("Unexpected exception reading document!" +e); 
14          System.exit(0); 
15      } 
16      . . .
17   }
18 }

The end result is the same -- the production of a DOM document. The means, however, is now generic. This code produces a factory object that can be used to produce DocumentBuilder objects. With the DocumentBuilder objects, we can produce the actual DOM document and go on our way.

The process is similar for SAX parsers. First obtain a SAXParserfFactory object and use it to obtain a SAXParser object. The SAXParser can then be paired with a handler as required. A short example is given below:

Listing 3:

00 import*;
01 import org.w3c.dom.*; 
02 import org.xml.sax.*; 
03 import javax.xml.parsers.*;
04 public class SAXParserExample { 
05    public static void main (String argv []) throws IOException { 
06  . . .
07  try { // Get the path to the file 
08      String xmlResource = "file:"    + new File(argv[0]).getAbsolutePath(); 
09      SAXParserFactory spf = SAXParserFactory.newInstance(); 
10      SAXParser sp = spf.newSAXParser();    
11      SAXHandler handler = new SAXHandler(); // some handler
12      sp.parse(xmlResource, handler);
13      ....
14      } 
15      catch (Exception e) { 
16          System.out.println("Unexpected exception reading document!" +e); 
17          System.exit(0); 
18      } 
19      . . .
20   }
21 }

Likewise, we could perform XSLT transforms via TransformerFactory and Transformer objects. Examples of this can be found in the JAXP specifcation.

But JAXP's real magic comes in its ability to actually obtain DOM documents, SAX parsers, and XSLT tranformation engines. The reference implementation comes with default parsers, etc., but at any time, you can specify alternatives using any or all of the system properties:

  • javax.xml.parsers.SAXParserFactory
  • javax.xml.parsers.DocumentBuilderFactory
  • javax.xml.transform.TransformerFactory

JAXP then reads the system properties and uses the specified parser, document or what not. With JAXP we get the best of both worlds -- the ability to use a completely generic API to access our XML, without losing the flexibility to choose our own parser.

The JAXP specification provides the details of exactly how the various factory objects must be implemented in order to work correctly.

JAXB -- Java Architecture for XML Data Binding

Current specification status: Current Version 0.21, with early access reference implementation.

JAXB (JSR 31) provides a similar conceptual mechanism to JAXP's wrapping of XML with Java objects. In fact JAXB is two things -- a toolset for creating a two-way mapping between XML and Java, and an API for accessing XML/Java objects.

A word of caution: currently, the JAXB specification is a working draft and potentially subject to substantial change.

Typically applications create, consume, and otherwise change XML data. While you could certainly write an application that used DOM or SAX to process data, such an application would be error-prone and tedious to develop. And ultimately, many developers would be doing the same thing for the same XML/DTD or schema combination.

What JAXB provides is a mechanism for generating the binding between arbitrary DTDs and schema into equivalent Java objects. The JAXB specification defines three specific areas of support:

  • The unmarshalling of XML documents into a representative object tree
  • The marshalling of trees representing XML data back into XML documents
  • The validation of trees representing XML data against defined constraints

In this article we will focus primarily on the ability of JAXB to generate Java classes that marshal and unmarshal XML into Java objects.

If we look more closely into the JAXB specification, we see that its power comes from its binding framework. The binding framework defines the abstract classes and interfaces that are implemented when we run the schema compiler. Specifically, the binding framework is composed of two packages: java.xml.marshal defining low-level primitives and clases for reading and writing XML; and java.xml.bind providing higher-level interfaces for marshalling, unmarshalling, and validating XML into and out of Java objects.

The marshal package provides a variety of subclasses for reading from files, streams, SAX and DOM trees. etc., all adding exceptional power to your JAXB-based applications.

More genererally, the javax.xml.bind package defines a number of classes including:

Populate Java objects from XML
Support generating XML from Java objects
Validate and re-validate Java classes to determine if they conform to the underlying DTD or schema
Map XML data to Java objects

Rather then continue to pore through the JAXB specification, an example might be more illustrative of these concepts.

The early access version of JAXB comes with a number of examples, the simplest of which is a traditional trade example whose DTD is shown below:

Listing 4: Stock.xml

<?xml version="1.0" encoding="US-ASCII"?>

A simple stock-trade DTD
@(#)trade.dtd 1.3 01/03/07

<!-- #[START] -->
<!ELEMENT trade ( symbol, quantity, limit?, stop?, date ) >

<!ATTLIST trade
action ( buy | buy-to-cover | sell | sell-short ) #REQUIRED
duration ( immediate | day | good-til-canceled ) "day" >

<!ELEMENT symbol (#PCDATA) >
<!ELEMENT quantity (#PCDATA) >
<!ELEMENT limit (#PCDATA) >
<!ELEMENT stop (#PCDATA) >
<!ELEMENT date (#PCDATA) >

Basically, trades contain the information we expect from a trade: the symbol, quantity, date, etc., as well as various trade attributes. If we run the schema compiler on the trade DTD, it generates a single class,, a snippet of which is shown below:

Listing 5:

/* Various imports removed */
import javax.xml.bind.ConversionException;
import ...
/* Various imports removed */

public class Trade
    extends MarshallableRootElement
    implements RootElement

    private String _Account;
    private String _Action;
    private String _Duration;
    private boolean isDefaulted_Duration = true;
    private final static String DEFAULT_DURATION = String.valueOf("day");
    private String _Symbol;
    private String _Quantity;
    private String _Limit;
    private String _Stop;
    private String _Date;

    public String getAccount() {
        return _Account;

    public void setAccount(String _Account) {
        this._Account = _Account;
        if (_Account == null) {

. . .

As one would expect, the trade DTD generated a number of fields corresponding to the fields and attributes of the DTD, as well as an equals method and marshal and unmarshal methods. But how do we go about using the newly created trade class?

Let's look at the driver application for the trade class packaged with JAXB.

Listing 6:

00 import*;
01 import javax.xml.bind.*;
02 public class TradeLister {
03    public static void main(String[] args) throws Exception {
04	      Dispatcher d = Trade.newDispatcher();
05	      Object ob = d.unmarshal(;
06	      System.out.println(ob);
07    }
08 }
Tradelister first imports the required support classes from javax.xml.bind and then creates a new dispatcher for trades. Tradelister then unmarshals any trade classes passed in via What is actually happening is that a newDispatcher() factory method (inherited by the Trade class generated from the trade.dtd) allows us to generate, in memory, representations of trades. We can use this factory method to instantiate Dispatcher objects, which are capable of marshalling and unmarshalling XML data. The object actually returned by unmarshal is in fact a Trade object. It would have been perfectly reasonable to code TradeLister as:

Listing 7:

00 import*;
01 import javax.xml.bind.*;
02 public class TradeLister2 {
03    public static void main(String[] args) throws Exception {
04	      Dispatcher d = Trade.newDispatcher();
05	      Trade ob = (Trade)d.unmarshal(;
06	      System.out.println(ob);
07    }
08 }

We could have then accessed the various Trade fields via their JavaBeans, like getters and setters. Likewise, if the Trade object contained child objects, we would obtain each via similar getters and setters.

The JAXB specification goes into a great level of detail about how marshalling and unmarshalling actually occur; interested readers should look more closely at the specification for more information.


The JAX Pack APIs add an exciting element to Web services development in a J2EE environment. In this article we saw how to access DOM, SAX, and XSLT without concern for the underlying provider, via JAXP. We saw how to wrap XML in Java Objects via JAXB. In the next article, we'll learn how to send XML messages using JAXM.

Return to