Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples

Hangin' with the JAX Pack, Part 3: Registries

by Al Saganich

This article is Part 3 of a four-part series on JAX, the Java APIs for XML. There are several APIs in the set. In the first article, I addressed the Java API for XML Processessing (JAXP) and the Java API for XML Binding (JAXB). In Part 2, we discussed the Java API for XML Messaging (JAXM), an interesting API for developing low-level services. There are still two more pieces of the JAX Pack: registration and a higher-level RPC abstraction. In this article, we'll look at JAXR, the Java API for XML Registries, for defining and accessing Web Services registries.

JAXR (JSR 93) is designed to provide a mechanism to access both ebXML- and UDDI-based registration services. JAXR is currently in version 0.7 (public review draft 2), dated Nov. 13, 2001. UDDI and ebXML, and registries in general, provide three distinct services:

Connecting registries and clients

JAXR provides a layer of abstraction above these three areas, allowing for registration of Web services and the ability to search for Web services that provide a specific service. Specifically, JAXR provides a pluggable API interface that allows registries to make their services available to JAXR clients. (The specifics of the JAXR Pluggable API is beyond the scope of this article. Developers interested in plugging their registry services into JAXR are encouraged to read the JAXR specification.) JAXR also supports client APIs.

Figure 1 shows these services conceptually. Developers expose their registratrion services by implementing the JAXR Pluggable API. Clients then connect to these services using JAXR client APIs.

Figure 1. JAXR client and provider APIs.

We are specifically interested in JAXR support for clients. JAXR-based applications need to perform two specific and distinct client operations. First, providers of Web services need to be able to register their services, along with adequate descriptions of the services. Secondly, interested client applications need a mechanism to search for services. JAXR provides both registration and searching capabilties.

A word of caution: the JAXR specification has only just reached the public draft state and no reference implementations existed at the time of this writing. Packages, interfaces, constants, etc. are subject to change. In fact, the current JAXR Specification and JAXR API Java docs don't match!

Searching the registry

Let's look at a concrete example of how we might go about searching for lumber yards. Listing 1 shows a complete example, based on both the JAXR specification and the JAXR API docs.

There are four main steps in searching a registry:

  1. Create a connection.
  2. Use the connection to obtain a handle to a Registry Service.
  3. Obtain a query manager from the registry service.
  4. Use the query manager to perform queries.

Listing 1: JAXRSearchClient.java

00 //
01 // Developed from the JAXR Spec and API docs
02 // both of which are subject to change
03 //
04 import javax.xml.registry.*;
05 public class JAXRSearchClient extends RegistryClient {
06  static String JAXRFactory = new String("JAXRConnectionFactory");
08  //
09  // The two onException and onResponse methods are defined by the RegistryClient
10  // interface to support asynch. messaging.
11  //
12  void onException() { };
13  void onResponse() { };
15  Connection getConnection(){
17    Context ctx = new InitialContext();
18    ConnectionFactory factory = (ConnectionFactory) ctx.lookup(JAXRFACTORY);
20    Properties props = new Properties();
21    props.put("javax.xml.registry.factoryClass","com.sun.xml.registry.ConnectionFactory");
22    // other connection properties. .
24    return factory.createConnection(props,this);
25  }
27  void Search() {
29    Collection sqals = new ArrayList(); // The search qualifiers
30    sqals.add(FindQualifier.CASE_INSENSITIVE_MATCH)
32    Collection namePatterns = new ArrayList();
33    namePatterns.add("%Lumber%");
34    Connection cn = getConnection();
36    //
37    // we could use the .setCredentials, setLocale etc on
38    // the connection at this point if required
39    //
40    RegistryService rs = cn.getRegistryService(); // implements the RegistryService
42    BusinessQueryManager bqm = rs.getBusinessQueryManager();
44    // find all the organizations that match our search
45    // there are better then 12 findOrganizationXYZ methods on BusinessQueryManagers!
46    BulkResponse orgs = bqm.findOrganizationsbyName(namePatterns, // what to search for
47     search, // lexical qualifiers
48     null); // sort qualifiers
51    // manipulate the organizations as a collection
52    Collection results =orgs.getCollection();
55  }
57 }

Let's look at Listing 1 in detail.

Line 4 imports the required registry classes from the javax.xml.registry package.

Previously in this series:

Hangin' with the JAX Pack, Part 1

Hangin' with the JAX Pack, Part 2: JAXM

The registry client interface defines two methods, onException and onResponse, used for asynchronous communcations. Connections require a class that implements this interface and so we support these methods, even though we will be doing everything synchronously.

Lines 15-25 define a convenience method, getConnection, which should look very familar to anyone who's ever done JMS development. In getConnection we use a Context object to access JNDI and obtain a JAXR connection factory object. We then use the connection factory to obtain a connection and return it for use in our searches.

The search method, defined in lines 27 and onward, actually does the real searching. Line 34 uses our getConnection convenience method to establish a connection to a registry service. We then use the connection to obtain an instance of a BusinessQueryManager object. BusinessQueryManagers are the heart of queries and,

A strong word of caution -- the various findOrganizationXXX methods in the JAXR specification differed significantly from the find method defined in the JAXR Java docs. Listing 1 should only be used to understand conceptually how JAXR searches might work.

according to the specification, they define 12 findOrganizationXYZ methods to allow for a variety of canned search mechanisms; these support everything from simple searches based on name matches through combinations of category, service, specification, and other ways to specify search criteria.

Lines 46-48 use the findOrganizationByName name method to perform a "white pages" search for any name containing the word "lumber".

Line 52 then returns the result as a collection we can interpret and use later with JAXM or JAX-RPC to actually bind to a Web service and use it.

Registering services

Now, let's look at how services are registered with JAXR.

JAXR support for managing registry entries is conceptually a bit more difficult than searching because registry entries have a life cycle. Lifecycle operations normally fall into three categories:

In order to support these operations, JAXR contains the notion of a business lifecycle manager object, which helps in adding, deleting, changing, and recategorizing services.

Let's look at the steps in adding a Web service to a registry:

  1. Create a connection.
  2. Define the service.
  3. Use the lifecycle management services to save the definition into the registry.

Listing 2 shows how we would go about registering a service into a registry:

Listing 2: JAXRRegister.java

00 //
01 // Developed from the JAXR Spec and API docs
02 // both of which are subject to change
03 //
04 import javax.xml.registry.*;
05 public class JAXRRegister extends RegistryClient {
07  //
08  // The two onException and onResponse methods are defined by the RegistryClient
09  // interface to support asynch. messaging.
10  //
11  void onException() { };
12  void onResponse() { };
14  Connection getConnection(){
16    // . . . Exactly like searching
17  }
19  void Register() {
21    Connection conn = getConnection();
22    Registry Service rs = conn.getRegistryService();
23    BusinessLifeCycleManager lcm = rs.getBusinessLifeCycleManager();
25    Organization org = lcm.createOrganization("Lumber Yards of Nashua");
26    org.setDescription("All the wood you'll ever need!");
28    ClassificationScheme cs = lcm.createClassificationScheme("ntis-gov:naics",
29     "North American Industry CLassification System");
31    // our unique UUID
32    infomodel.Key ckey = lcm.createKey("uuid:C0AABBCC-3333-AB66-000011113333");
33    cs.setKey(cKey);
34    Classification cf = (Classification)lcm.createClassification(cs,"Lumber and Lumber Yards","11111");
36    Collection classifications = new ArrayList();
37    classifications.add(cf);
39    org.addClassifications(classifications);
40    Collection orgs = new ArrayList();
42    orgs.add (org);
43    lcm.saveOrganization(orgs);
44  }
46 }

Let's look at this code in detail.

Line 4 again imports the required JAXR classes.

At line 21 we create a connection to the registry service provider; at line 22 we use the connection to obtain an instance of a registry.

At line 23 we then create our BusinessLifeCycleManager object. We can use this object to perform a variety of lifecycle management operations.

Lines 25 to 34 define the Web service by describing the classification scheme we will use, the description of the service, and its ID. Under normal circumstances, the UUID would be provided by the registry service provided, such as ebXML, to avoid clashes, although JAXR allows for user-defined IDs. An in-depth description of the classification interfaces and objects is defined in the JAXR specification.

Related Reading

Java and XML, 2nd Ed.Java and XML, 2nd Ed.
By Brett McLaughlin
Table of Contents
Sample Chapter
Full Description
Read Online -- Safari

Once we've defined our service, we simple add it to the registry. Line 43 uses our lifecycle manager to add the new Web service.

Once the service has been added, it can be used by any Web service, JAXPack-based or otherwise.


The JAXR APIs are interesting and easy to use. Perhaps all the more so because they completely hide the SOAP-based underpinnings of communcations with various registries. A word of caution, however: numerous differences were found between the JAXR specification, the Java docs for JAXR, and the provided interfaces. JAXR is clearly an evolving specification.

In the final article in the series, we'll look at JAX-RPC.

Al Saganich is BEA Systems' senior developer and engineer for enterprise Java technologies, focused on Java integration and application with XML and Web services.

Previously in this series:

Hangin' with the JAX Pack, Part 1 -- In this three-part series, BEA Systems' Al Saginach takes a look at the JAX Pack, JAVA APIs for providing XML-based Web services handling XML. This week Al looks at JAXP (for XML processing) and JAXB (for XML binding). Next week: XML messaging with JAXM.

Hangin' with the JAX Pack, Part 2: JAXM -- Al Saganich examines JAXM, the Java API for XML Messaging, and shows how it provides support for accessing various messaging formats.

Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.