JSR 109: Web Services Inside of J2EE Appsby Al Saganich
Over the last six months, a number of standards have begun to emerge in the areas of Web services' lifecycles, security measures, collaborations, and transactions. JSRs have emerged to begin the process of defining, in a standard way, the different aspects of how Web services might be supported in a J2EE-compliant application server.
JSR 109 specifically discusses local client access to Web services, server lifecycle, and deployment of Web services. JSRs 104, 105, and 106 combine to describe various aspects of Web services security, including APIs for trust services, digital signatures, and encryption. JSRs 156 and 157 define a basis for supporting transactions and collaborations between Web services, including support for 2PC (JTA) and business-style transactions. In this article, we will examine the intent of JSR 109 and examine its impact on Web services implemented in a J2EE environment.
JSR 109: Web Services For J2EE
Current specification status: Version 0.3
(public review version 1.0) dated 15-April-2002.
Introducing JSR 109
Over the past few years, J2EE has emerged as the dominant standard for serving up information on the Web. A large number of standards have evolved, of which Web services is one of the most recent, to place application functionality behind Web front ends. First there were servlets and JSP, as well as stateless session Enterprise Java Beans. Over time, the EJB specification changed and grew to support stateful, then entity, and eventually message-based semantics.
Its only logical to assume the J2EE arena will continue to grow and evolve. JSR 109 is one of the latest specifications to expand J2EE support into new areas. JSR 109 effectively defines how a J2EE application server could be expanded to provide native support for deploying, managing, and accessing Web services in a standard fashion.
Specifically, JSP 109 covers a number of important areas:
- Client-side programming model -- how J2EE applications can access Web services as if they were "traditional" remote objects.
- Server-side programming model -- how Web services can be implemented as servlets and stateless session EJBs and their lifecycle.
- Web service deployment and deployment descriptors -- how Web services might be deployed in a compliant application server.
In this article, we will examine various areas of JSP 109 to understand the benefit of each. But as you read this article, please remember that specifications are designed to describe a solution to a problem. Often we look at a technology and think only in terms of what it does, losing sight of the problem it was meant to solve. As we read specifications, we should continue to ask, "What problem does this solve?" A specification should describe a solution to a problem, without being too broad or too narrow in scope.
First and foremost, JSP 109 attempts to define a programming model for implementing Web services so that outwardly, they appear exactly the same to the calling application, regardless of how they were implemented. Because Web services are controlled and defined by many other specifications, JSR 109 cannot require any changes beyond the scope of how a Web service is implemented and deployed in a compliant application server. We'll look at the various aspects of the development and deployment model shortly.
In addition, JSP 109 attempts to define a client-side programming model that mimics other J2EE programming models; developers familiar with "traditional" remote methodologies will be familiar with JSR 109. By "traditional," we mean that JSR 109 defines a client-side programming model that is consistent with other J2EE applications, uses JNDI, etc., to obtain access to a remote interface and then call into the object it references.
Note: A number of members of the voting Web services communities, such as Sun and BEA, have expressed significant reservations with the scope of JSR 109. For a complete review of comments, see the voting page.
Client Programming Model
The purpose of the client-side programming model of JSR 109 is to clearly define how Java applications might access a Web service locally in a manner similar to how EJB access works today. The problem is one of complexity. Other JSRs define mechanisms for accessing Web services not residing locally within an application server; however, such methods add a significant level of programming complexity to client applications. Accessing a Web service from within the application server that defines it should be a straightforward process. The client-side programming model in JSR 109 defines a mechanism for accessing a locally-deployed Web service in a simple and well-understood manner.
JSR 109 defines three specific client programming models -- client-managed port access, container-managed port access, and dynamic port access. We will be concentrating on client-managed access, which defines an interface, based on the original WSDL, to the Web service. Using client-managed access, an application requests a port to a specific interface. Container-managed port access acts much like client-managed, except that the container manages calls to the instance directly, and the client requests a generic port that might be used to access multiple different instances.
A Note on Ports
Before we jump into accessing a Web service, we must first understand the concept of ports. A port is effectively an instance of a Web service. A client application accessing a Web service must ask a service interface for access to the service, at which point the application server might either serve up an existing instance or create a new instance to handle the request. Readers familiar with EJB programming will find the client-side programming model for JSR 109 very familiar.
With dynamic port access, no prior knowledge of the WSDL definition is required, and calls are generated on the fly. While significantly more robust, dynamic access to any object hasn't proven to be very useful in real-world applications. In the future -- if or when dynamic programming becomes more prevalent -- such access methods will prove valuable. For the remainder of this article, we will work with the more traditional container-managed port access model, where a definition of the Web service interface is known to the client beforehand. We'll look at client-managed and container-managed port access later.
Step 1: First we obtain an
as we would in any JNDI client application. (The specifics of JNDI
are beyond the scope of this article. Interested readers are directed to the
Javasoft JNDI tutorial.)
When we examine the Web services deployment, we will understand the specifics
of the actual name used to access the Web service; until then, we'll need to
take the Web services name on faith. Clearly the application server would need
to ensure that the actual Web service was bound into the JNDI tree.
00 InitialContent ic = new InitialContext(); 01 SomeSpecificServiceInterface srv = (SomeSpecificServiceInterface)ic.lookup (java:comp/env/service/SomeSpecificServiceInterface); 02 ServiceInstance si = (SomeSpecificService)srv.getServiceInstancePort();
If we look closely at this snippet, we see a traditional JNDI lookup on line
00. On line
01, we obtain an specific instance of a generic
object interface. All services are required to implement the
which defines a number of common methods for accessing a service, such as returning
specific instances. Anyone familiar with the EJB specification will see the resemblance
Services interface and an EJB home interface. On line
02, we then
obtain an instance of a remote object, which defines the actual method calls
on the instance of the object.
Client-managed port access is typically used when a Web services definition
is completely known at development time. If for some reason the application
server could not return an instance supporting the cast operation on line
an exception would be thrown.
Example 2. Container-managed port access.
00 InitialContent ic = new InitialContext(); 01 Service srv = (Service)ic.lookup (java:comp/env/service/SomeSpecificServiceInterface); 02 ServiceInstance si = (SomeSpecificService)srv.getPort();
Example 2 differs only slightly from Example 1. Specifically, on line
01, we now request a generic instance of the object. No interface was specified,
so the container is free to return any appropriate available instance
that matches the requested JNDI name. Line
02 also differs in that we use a
getPort() call rather
then a specific named
call, as we did in Example 1.
The specification states that container-managed port access might be used when
the client only accesses the Service definition for the object.
assumes that the client knows about a specific interface that the service might
not support. If the container did not understand the requested cast, an exception
would be thrown at run time. More likely, the client did not have a complete
WSDL definition at build time, and therefore cannot use the
get<some port>Port() method, but
rather the client would cast the appropriate instance type --
a seemingly more likely possibility.
Server Programming Model
The server programming model is perhaps the most important aspect of JSR 109. The ability to understand how a Web service behaves during the various phases of its lifecycle allows the Web service developer to create services that behave predictably under a variety of conditions. The EJB specification defines the lifecycle for the various EJB types. JSR 109 goes to the next level and extends the EJB model to define how Web services act in a Web services container. JSR 109's treatment of server programming is an attempt to solve the problem of consistency of behavior.
A Quick Background Note
Web applications and EJBs normally execute inside of "containers." A container provides all of the services that the EJB or Web application might require at runtime. Transaction, JNDI, JDBC, and similar services are all provided through the container. Normally, there are two types of containers within an application server -- Web application and EJB containers. Both offer similar services, such as lifecycle management, for the object in question, but differ slightly, based on what service they provide. Web application containers know how to load servlets; EJB containers know how to load EJBs.
Before we get into the specifics of JSP 109, let's understand what is required to support Web services in a J2EE-compliant manner. First and foremost, the implementation of a Web service should be transparent to the client. The fact that a Web service is implemented within an application server in Java should in no way change the client's view of the service behavior. Additionally, we'd like to be able to use our Web service on a variety of application servers. Thus, the programming model should be portable and robust, to support both today's implementations and those of tomorrow.
Of lesser, but still high, importance is seamless integration with existing J2EE services, such as JDBC. We'd like our Web services to be able to take advantage of the advances already available in J2EE in a simple way, without compromising the integrity of the service itself.
With these goals in mind, JSP 109 defines two specific support areas for Web services: stateless session bean and servlets. JSR 109 is disappointing in that message-driven beans are clearly omitted without explanation. Message beans allow for scalable asynchronous messaging, an important aspect of Web services. While the behavior of message beans can be simulated with either a stateless session bean or a servlet, additional coding is required.
Ports are an important concept within Web services, and JSR 109 defines how ports are mapped to services within a J2EE application server. Ports within a Web service are similar in concept to instances in a JVM.
- WSDL: The definition of the Web service APIs. WSDL isn't really a part of the Web service, but rather defines how the Web service can interact.
- Service Definition Interface (SDI): The SDI for a Web service defines the actual methods supported by the service. Remember, service definition is separate from service implementation.
- Service Implementation: The actual implementation of the Web service. In JSR 109, this is either a stateless session EJB or a servlet. Normally, a service implements the SDI directly and may or may not actually implement the Java interface defined by the SDI.
- Security Roles: While JSR 109 touches on security roles, it effectively inherits security role behavior from the servlet and EJB specifications.
Pages: 1, 2