Over the past three years, the Java 2 Platform, Enterprise Edition (J2EE) has evolved into the premiere server-side solution for reliable, scalable enterprise applications. In that same time, the standardization and explosive adoption of XML-based protocols have paved the way for Web services and spawned an industry-wide focus on cross-platform interoperability. This article explores the intersection of these two phenomena in the next release of the enterprise Java platform, J2EE 1.4.
Sun Microsystems is expected to finalize the J2EE 1.4 specification this fall, with highly anticipated vendor implementations hitting the market in first quarter 2003. Core technologies, including servlets, JSP (JavaServer Pages), and EJB (Enterprise JavaBeans), are being revised; however, most changes focus on integrating extensive XML support throughout the platform. The various specification revisions include a few hidden gems, like EJB 2.1's new container-managed timer service. But the most high-profile changes involve XML support and new Web services semantics within the J2EE client and server environments.
This article assumes some familiarity with basic J2EE, XML, and Web services concepts. Whether you're a project manager, Web application developer, or a hard-core middleware and distributed applications guru, this article provides a clear understanding of the enterprise Java platform's direction and how J2EE 1.4 will support emerging Web services standards.
J2EE 1.4's XML support
Sun introduced the Java APIs for XML, or Java XML Pack, at JavaOne in June 2000, reintroduced them as part of the Web Services Developer Pack (WSDP) in summer 2001, and will include many of these APIs in the J2EE 1.4 platform this winter. The Java XML Pack enriches the Java platform with a wide spectrum of XML support. A brief recap of a Web service's lifecycle serves as a good template for understanding where each of the various Java APIs for XML fits into the J2EE platform.
Web services must provide their service's definition, usually in the form of a WSDL (Web Services Description Language) document. They also must advertise their availability in a registry such as UDDI (Universal Description, Discovery, and Integration) or ebXML, both of which are evolving through the nonprofit e-business consortium OASIS (Organization for the Advancement of Structured Information). Ultimately, Web services require runtime binding and RPC (remote procedure call)-style interaction, both synchronous and asynchronous. This involves the exchange, processing, and potential transformation of XML documents.
The Java API for XML-based RPC (JAX-RPC) is the backbone of J2EE 1.4's Web services support, offering a fairly complete Java-to-SOAP (Simple Object Access Protocol) abstraction with the RMI (Remote Method Invocation) programming model's familiar semantics. JAX-RPC also includes tools for generating a WSDL document from a Java Web services interface and vice versa. The Java API for XML Registries (JAXR) provides a pluggable abstraction for Web services registry operation, lookup, and interaction. Finally, the Java API for XML Processing (JAXP) is the glue that binds all things XML, giving J2EE portable APIs for XML processing with support for pluggable parsers and transformers.
I'll highlight each of these APIs.
Sun introduced JAXP into the J2EE 1.3 platform revision in fall 2001. JAXP provides a set of XML processing APIs that are portable across vendors. It supports pluggable DOM (Document Object Model) and SAX (Simple API for XML) parsers, as well as pluggable XSLT (Extensible Stylesheet Language Transformation) engines. The idea is to develop your XML processing code once and then simply reconfigure the parser or XSLT engine at deployment.
JAXP supports DOM Level 2 with a set of APIs for building, traversing, and manipulating a DOM tree in memory. JAXP can also perform SAX 2.0 event-based parsing. In that scenario, developers provide an implementation of a special JAXP interface containing methods that are called as the parser encounters elements in an XML document. SAX obviously has an advantage in that it provides some opportunities for scalable design, but DOM offers richer interaction and processing of an XML document.
XSLT has materialized as a huge part of the XML revolution, enabling XML data to adapt to various schemas through transformation. JAXP supports XSLT 1.0, which lets Java developers write portable, maintainable transformation code. JAXP provides programmatic access to transformation output in numerous formats, even as a DOM or SAX parser, allowing chained processing and transformations.
The JAXP specification has been updated independently of the version required by J2EE; namespaces and events were added to JAXP 1.1. Despite JAXP's effectiveness, many Java developers still prefer to use popular third-party APIs, such as JDOM, to fulfill their more advanced manipulation and parsing requirements. While JAXP has slowly evolved to incorporate similar best-of-breed functionality, its portability focus will likely continue to carve a niche for these third-party APIs.
JAX-RPC provides Java with a standard API for RPC-style exchange of XML messages, using SOAP as the underlying protocol. One of JAX-RPC's development goals is to leverage Java RMI's familiar programming semantics. Both technologies rely on stubs and skeletons to encapsulate the details of communication, parameter marshalling, and similar infrastructure concerns. Both an RMI service and a JAX-RPC Web service implement the
java.rmi.Remote interface and bear similar requirements for throwing remote exceptions. JAX-RPC obviously offers far greater interoperability than traditional Java RMI in that it can access Web services implemented in other languages besides Java.
Simple JAX-RPC clients can be built using generated stubs that allow the developer to consume Web services using a JavaBean-like interaction model. More complex interactions can also be achieved using the Dynamic Invocation Interface (DII). With DII, the container generates JAX-RPC stubs at runtime and then dynamically invokes methods. In this regard, the DII provides reflection-like capabilities to Java applications that dynamically consume Web services.
JAX-RPC also addresses the server side with an endpoint model that allows Java classes to be exposed as Web services by simply implementing the JAX-RPC
javax.xml.rpc.Service (which actually extends
java.rmi.Remote). JAX-RPC implementations include a compiler (xrpcc) that developers can use to generate a Java
Service interface from a WSDL document and vice versa.
One common gripe with some of JAX-RPC's early access releases was its limited type support. At the time of this writing, JAX-RPC supports most primitive types (for example, string, Boolean, byte, double, float, and integer) and even marshalls simple collections of these types. In reality, the types supported by JAX-RPC mirror the types supported by the SOAP protocol. Furthermore, serialization and deserialization interfaces are exposed in JAX-RPC for developers and (more likely) tool vendors to roll their own behaviors. Given that JAX-RPC facilitates easy Web services consumption from within a Java environment, the API will likely grow popular on the client side. Server-side usage often proves quite transparent to developers. I will return to this point in the discussion of servlet and EJB Web services later.
JAXR provides Java with a standard mechanism for accessing registry services. Java Web service endpoints leverage JAXR to advertise their availability in a registry, and Java Web service clients (consumers) use JAXR to discover and interrogate other Web services' capabilities.
JAXR 1.0 supports pluggable providers, insulating developers from lock-in to vendor-specific APIs when building simple registry-aware Web services. JAXR also supports profiles, which provide an extensibility point for portable registry interaction through finer-grained APIs when necessary. JAXR clients can easily interrogate providers at runtime to discover their capability level.
Many articles have delved into JAXR, UDDI, and ebXML. I recommend exploring these topics further, especially for developers who plan to implement dynamic Web service clients and registry-aware Web services (see Resources). The specifics of JAXR registry operation and interaction (for example, lifecycle, searching, and publishing) reach beyond this article's scope.
JAXB, JAXM, and SAAJ
A few additional XML-related APIs not ready for inclusion in J2EE 1.4 are worth mentioning—especially considering that a future revision will require them.
The Java Architecture for XML Binding (JAXB) offers a mechanism for automating mappings between XML DTDs (document type definitions) and Java objects. The JAXB expert group is currently updating the specification to support XML Schemas and a more flexible, pluggable approach to marshalling and unmarshalling. Sun has already confirmed that JAXB 1.0's first official release will not be API-level compatible with the current early access release. As such, most developers will continue to rely on third-party products or simply roll their own parsing and processing code with DOM/SAX until JAXB is finalized in fourth quarter 2002.
The Java API for XML Messaging (JAXM) supports the sending and receiving of XML messages through a standardized API. Based on a service provider interface (SPI), JAXM allows developers to write portable synchronous and asynchronous XML messaging code that they can use with interchangeable providers. Although not included in the J2EE 1.4 release, JAXM is a tremendously important member of the Java XML Pack that should not be overlooked.
To easily achieve simple higher-level JAXM usage, extend
JAXMServlet and implement a single
JAXMServlet provides the Web tier with a lightweight XML-based answer to message-driven beans (MDBs). The latest EJB specification expert group is currently tasked with retrofitting MDBs to support pluggable messaging protocols, allowing MDBs to be used for asynchronous JAXM message processing in addition to their current limited use as JMS message consumers. Support for pluggable messaging will not be ready for J2EE 1.4, but inclusion in EJB 2.2 is anticipated.
In its original state, JAXM provided an abstraction for XML messaging and SOAP. In an effort to avoid unnecessary dependencies between JAX-RPC and JAXM, which should represent two distinct forms of XML-based communication, the abstraction for SOAP and SOAP with attachments, as provided in the
javax.xml.soap package, moved into a new JSR (Java Specification Request).
SOAP with Attachments API for Java (SAAJ) 1.1 aims to insulate developers from the SOAP protocol's specifics, just as servlets did for HTTP. Coding low-level SOAP calls is not only time-consuming, but also extremely error prone. SAAJ will provide some much needed resiliency to any Java code that makes low-level SOAP calls. Unlike JAXM and JAXB, SAAJ will be included as a J2EE 1.4 requirement. After all, how would you build Web services without SOAP?
Many Web services standards are still considered to be somewhat volatile moving targets, especially in the areas of security, transactional support, collaboration, and encryption. We'll likely see many revisions and new specifications in this space over the next few months.
Now that we've looked at the various technologies that will support XML development and Web services standards within a Java environment, let's explore the changes to some familiar J2EE components that will allow them to both consume Web services and be exposed as Web services.
Overview of J2EE Web services
JSR-109, Implementing Enterprise Web Services, defines how to implement Web services in the J2EE platform. Specifically, JSR-109 defines client-side and server-side programming models, and new deployment semantics.
The client-side programming model intends to provide transparent access to local Web services similarly to how you might access an EJB. Just as EJBs have remote (or local) component interfaces and separate enterprise bean implementation classes, all Java Web services have a
Service interface (and corresponding WSDL), and a
Service implementation. In case you were wondering, the JAX-RPC specification's proposed client-side model is intended for Web services consumption in a remote container and proves too cumbersome for use with local Web services.
Clients can look up service interfaces using JNDI (Java Naming and Directory Interface) in many ways. When the WSDL is known at development time, a Java
Service interface can generate in advance. Clients can request a port to specific service interfaces using a client-managed port access model. Similarly, with container-managed port access, a client requests a generic port, allowing the container to delegate calls to various service instances. When the WSDL is not known in advance, dynamic port access provides a powerful mechanism for deferring stub generation until execution time. While not particularly useful within today's current real-world applications, dynamic port access is anticipated to gain some popularity with the emergence of next-generation composite Web services.