Anda di halaman 1dari 7

SETT June 2007 - JSR 181: a Java Simplification Request

1 of 7

Follow @ObjectComputing

http://jnb.ociweb.com/jnb/jnbJun2007.html

Home | Software Engineering Tech Trends Archive | OCI Educational Services

1,541 followers

Tweet

RSS

JSR 181: a Java Simplification Request


by
Michael Easter,
Senior Software Engineer
with Advantage Consulting, Inc.,
an OCI affiliated company.

Introduction
Historically, web services in Java have vexed developers with myriad specifications and complex solutions. Surrounded by legions of W3C specs, JSRs, and XML descriptors,
these developers endured complexity while other Java communities (such as EJB3, Seam and Guice) celebrate the elegance of Java 5 and beyond. Moreover, with the
success of the sleek REST school of web architecture, there is a fitting rallying cry: "hear our Java Simplification Request for web services! "
If only there were a world in which Java developers express web services in a compact manner, where tools assist with the mundane, "plumbing" details. This world is a far
cry from the status quo, and certainly appeals. For example, what if web services were as easy as:
@WebService
public class Concatenator {
@WebMethod
public String concatenate(String a, String b) {
return a + " " + b;
}
}

Welcome to the world of JSR 181: the above is a bona fide web service. JSR 181, "Web Services Metadata for Java", rescues downtrodden web services developers with a
simple, annotation-based development model for common web service tasks. Combined with a lightweight HTTP server in Java 6, JSR 181 enables rapid prototyping of web
services (WS) and brings WS development into the modern era of Java.
This article has two goals:
A bewildering mix of JSRs comprise the Java WS space, both in terms of volume and the subtle relationships among them. We almost need a JSR Modeling Language
(JML) to communicate! Defining JML is too ambitious, but the key JSRs are examined in a historical context, so as to set the stage for JSR 181.
Examples explore the JSR 181 development model.
It is assumed that the reader understands web services as an approach to distributed computing, and has a basic knowledge of web service constructs (e.g. WSDL, SOAP).
All examples require JDK 1.6.x.

Setting the Stage


There are two main eras of web services in Java: JAX-RPC and JAX-WS. Articles on both topics refer to several JSRs and their implicit relationships. This section provides a
bird's eye view of the landscape.

JAX-RPC 1.x
JAX-RPC represents the first version of web services in Java. See the graphical overview below. Some key points:
The primary spec, JSR 101 ("Java APIs for XML-based RPC"), defines the APIs and conventions for the Java platform, including the WSDL/Java mapping, the SOAP
binding and SOAP handlers. Version 1.0 was released in mid-2002.
Due to scheduling concerns, the JAX-RPC team elected to define its own facilities to bind data between Java and XML. This was in addition to other, more generalized
data binding solutions.
The state-of-the-JVM in this timeframe was JDK 1.4. JSR 88 defines the general deployment API for J2EE. JSR 109 ("Implementing Enterprise Web Services")
implements this API for the WS space. Note that the best practice of the time was XML-based deployment descriptors: i.e. artifacts to describe web services at
deployment time.
Version 1.1 of JAX-RPC appeared in mid-2003 with support for the WS-I Basic Profile 1.0, to improve interoperability with other technologies.

JAX-WS 2.x

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

2 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

Though initially met with considerable excitement, there are problems with JAX-RPC 1.x: the implementation is complex and competing technologies/philosophies (e.g.
Apache Axis, REST) offer simplicity that is seductive, despite being non-standard. Also, new specs and standards render some of the machinery of JAX-RPC 1.x (e.g. data
binding) as obsolete. Most of all, since the release of JAX-RPC, the Java landscape itself underwent seismic shifts, particularly with respect to EJB.
Seismic Shifts
Initially, tools (e.g. XDoclet) assisted with the generation of deployment descriptors. Later, Java 5 brought the promise of annotations. In recent years, prominent authors
railed against the complexity of J2EE and EJB. Alternative frameworks (e.g. Ruby on Rails) introduced simple, Zen-like philosophies, such as "prefer convention over
configuration". All of these forces culimated in a shift against the explicit use of complex deployment time descriptors, and even XML configuration. EJB3, Seam and Guice
clearly reflect this shift.
JSR 224
For version 2 of WS in Java, the technology was renamed as JAX-WS 2.0. Just as JSR 109 is the primary spec for JAX-RPC, JSR 224 "Java API for XML-Based Web
Services", is the central document for JAX-WS. Some of the spec's stated goals pertain to evolving standards:
JAX-WS adds support for SOAP 1.2 in addition to SOAP 1.1.
JAX-WS will support WS-I Basic Profile 1.1 as it continues to evolve.
JAX-WS may support WSDL 2.0 in JAX-WS version 2.1+
However, the following goals are more interesting:
JAX-WS delegates data binding of Java/XML to JAXB 2.x (aka JSR 222).
JAX-WS "aligns with and complements" the annotations defined by JSR 181. That is, just as JAX-RPC/JSR 109 defines a deployment time facility for the Java/WSDL
mapping, JAX-WS works with JSR 181 to define a development time facility for this mapping, using Java 5 annotations (aka JSR 175).
See the graphical overview below. There are several themes here:
JAX-WS uses delegation to leverage facilities provided by the modern JDK (JAXB and annotations). This is classic division of labor. Note: the diagram shows JSRs, yet
we can loosely apply the OO ideas of composition and encapsulation.
Within the JAX-WS space itself, JSR 224 delegates some work to JSR 181. More on this coming up.
With development time annotations, clearly JAX-WS responds to the criticisms of JAX-RPC with respect to the complex, antiquated nature of deployment descriptors.

JSR 181 within JAX-WS


The full JAX-WS spec (JSR 224) exceeds the scope of this article but, as noted, it defines the architecture for "WS Version 2." Clearly, it relates to JSR 181. What is the
relationship? Some answers come from the introduction of the JSR 181 spec:
JSR 181 "defines a standard for building and deploying Web Services without requiring knowledge and implementation of generalized APIs and deployment
descriptors." It "addresses the need to simplify... development of server applications that conform to SOAP and WSDL standards."
"It is not a goal ... to support every feature or enable the creation of every Web Service possible...." "The goal is to make it easy to build the most common types of
Web Services."
In short, JSR 181 is "Web Services Lite": all of the common WS functionality, without that complex aftertaste. In the parlance of OO design, JSR 181 is a facade design
pattern: a simpler interface to the full-blown JSR 224 (see diagram below). It truly represents a "front-end" to JAX-WS as it requires the presence of JSRs 109, 224 and
175.
Mercifully, the JAX-WS 2.0 reference implementation contains all of the WS-oriented JSR solutions and is bundled in Java 6, along with a lightweight HTTP server. This
allows us to experiment with JSR 181 out-of-the-box.

A Closer Look
The stage is set for JSR 181: let's dig in.

The Development Model in JSR 181

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

3 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

In the JAX-WS world, a web service requires these artifacts:


a WSDL document stating the contract of the service
a service endpoint interface (SEI) as a Java representation of the WS interface
a service implementation bean (SIB) as the Java implementation of the SEI
deployment descriptors which link everything together
JSR 181 requires only the SIB (i.e. the business logic). Annotations are used to generate the other artifacts. No doubt, annotation of business POJOs should be music to the
ears of the long-suffering WS developers.
There are several programming models defined in JSR 181 (only the first is required by implementations):
Start with Java. The developer writes an annotated Java class. The JSR 181 processor accepts the class as input and generates the WSDL, schema and deployment
descriptors.
Start with WSDL. Here, an implementation-specific tool accepts an existing WSDL file and produces: a Java SEI and Java classes representing the schema and
message parts specified by the WSDL contract. The developer must write the SIB that satisfies the SEI.
Start with WSDL and Java. In this model, the developer uses JSR 181 annotations to map the methods of Java SIB to an existing WSDL contract.
The examples in this article use the "Start with Java" model.

Example 1: Concatenator
Before listing all of the available annotations in JSR 181, we'll start small, to get a view of the landscape of the JAX-WS tools. The first example (available here) is a trivial
"string concatenation" service.
Server Side Concatenation
Let's begin with the service implementation bean in Java:
package com.ociweb.demo;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.Endpoint;
@WebService
public class Concatenator {
@WebMethod
public String concatenate(String a, String b) {
return a + " " + b;
}
}

Note the annotations on this simple class, which clearly denote a web service and a "web method." Amazingly, we are done with development and can start testing the web
service! The JSR 181 processor will take care of the rest. To prove it, we write a main method to publish the service to the HTTP server contained in Java 6:
public static void main(String[] args) {
// e.g.
// publish.url = http://localhost:9998/concatservice
String publishUrl = System.getProperty("publish.url");
if( publishUrl != null & publishUrl.length() > 0 ) {
System.out.println("publishing service at: " + publishUrl);
Concatenator concatenator = new Concatenator();
Endpoint endpoint = Endpoint.publish(publishUrl,concatenator);
} else {
System.err.println("usage: Concatenator publishUrl");
}
}
The main method creates an instance of the SIB, and calls Endpoint.publish(). The first parameter, a URI, specifies the address and transport/protocol. The current
javadoc states that for a 'http:' URI, it is assumed that the SOAP 1.1/HTTP binding is used. The publish method uses a default configuration to create the necessary server
infrastructure for publication.
Ant takes care of the next steps (see build_server.xml for details):
Run the Java6 apt tool on the source code. The JSR 181 processor will generate the necessary artifacts; apt compiles the Java code as well.
Run the Concatenator.main() method.
Once the server is running, we can point a browser to http://localhost:9998/concatservice?wsdl:

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

4 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

Presto! With stunning ease, the web service is available, and follows these JSR 224 conventions:
The targetNamespace for the WSDL is the Java package, with reversed tokens.
The identifiers for service, port, binding and other WSDL elements follow the natural convention by decorating the original SIB name, Concatenator.
The schema types are published to the URI: http://localhost:9998/concatservice?xsd=1
If we point the browser to the URI of the schema types:

We see that the types follow a similar, logical convention. However, there's more: the JSR 181 processor generates these classes for us. In the example directory, you can
find the generated Java classes Concatenate and ConcatenateResponse. Note how they are annotated with JAXB meta-data. These classes are entirely inline with the
sophisticated JSR 224 conventions.
Client Side Concatenation
Here is the simple client class:
package com.ociweb.demo;
class Client {
public static void main(String args[]) {
// create service
ConcatenatorService service = new ConcatenatorService();
// get the port
Concatenator concatProxy = service.getConcatenatorPort();
// Invoke the remote method
String a = "Hello";
String b = "Web Services!";
String resultStr = concatProxy.concatenate(a,b);
System.out.println("result = " + resultStr);
}
}
This class simply uses a ConcatenatorService object to acquire a proxy for the web service operation, and then uses it with concatProxy.concatenate. Note there are no
annotations on this class: where do the other classes originate? The answer is another JAX-WS tool, wsimport. The Ant build on the client side works like this:
Use the wsimport tool to generate the client side support classes for the web service. The generation is predicated on the same WSDL URI shown earlier: wsimport
accepts the WSDL as input and generates/compiles the classes. This example uses a parameter to "keep" the generated classes for viewing.
Compile and run the Client class above
The output from the client is:
$ ant -f build_client.xml
Buildfile: build_client.xml
clean:
[delete] Deleting directory C:\measter\src\jsr181\ex1\client\classes
[delete] Deleting directory C:\measter\src\jsr181\ex1\client\generated
init:
[mkdir] Created dir: C:\measter\src\jsr181\ex1\client\classes
[mkdir] Created dir: C:\measter\src\jsr181\ex1\client\generated

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

5 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

build_client:
[javac] Compiling 1 source file to C:\measter\src\jsr181\ex1\client\classes
run_client:
[exec] result = Hello Web Services!
BUILD SUCCESSFUL
Total time: 11 seconds

Recap
Example 1 represents a complete round-trip from client to server for a trivial web service. Note the compact amount of code and how it concentrates on the business logic
for the task at hand. With JSR 181, Java WS development joins EJB3 in the modern era of annotations.

The Annotations
The last example demonstrates the JAX-WS tools. However, the annotations are the heart of JSR 181. The table below gives a broad look at the available annotations:
Annotation
@WebService

Description
Marks a class/interface as a web service
Allows overrides for outer WSDL attributes: targetNamespace, wsdlLocation, portName

@WebMethod

Customizes an exposed WS operation (or excludes a method from WS publication)


Allows overrides for the name of the wsdl:operation

@Oneway

Denotes a web method as having one input message and no output

@SOAPBinding

Allows a WS or web method to customize mapping from WS to SOAP protocol


Defaults are DOCUMENT/LITERAL/WRAPPED but each dimension can be altered, e.g. setting style=RPC

@WebParam

Customizes the mapping from a Java param to a WS message part


The legal usage and behavior depends on RPC vs DOCUMENT style, etc

@WebResult

Analogous to WebParam, but for the return value

@HandlerChain Advanced functionality to associate WS with external handler chain


The most effective way to learn a given annotation is to modify the server Java class in Example 1, run the HTTP server from Ant and view the resulting WSDL in the
browser. Also, one should examine the generated Java classes. Here is a starting example to try in this interactive manner:
package com.ociweb.demo;
import
import
import
import

javax.jws.WebService;
javax.jws.WebMethod;
javax.jws.soap.SOAPBinding;
javax.xml.ws.Endpoint;

@WebService(
name="myConcatenatorType",
serviceName="myConcatService",
targetNamespace="http://reversed.when.normally.reads"
)
@SOAPBinding(
style=SOAPBinding.Style.RPC
)
public class Concatenator {
// as before
}

Example 2: Acme Web Service


This example, though unabashedly contrived, illustrates more of the JSR 181 annotations.
The scenario: Superheroes, like many enterprises, have concentrated on their core competencies and have farmed out the manufacturing of their super-materials to
specialty factories. Acme is one such manufacturer; it has a division to support the "arachnid class" of superhero, which has strong demand for custom-made super silk. In
the past, the superheroes have interfaced with Acme's Arachnid Division through legacy technologies. Now, Acme wants to join the modern era with a new, well, "web
service."
Acme has selected Java and JSR 181 as their technology. The specific goals include:
Provide a web service that supports 3 operations:
1. Request an estimate for a quantity of web material
2. Place an order for a quantity of web material
3. Optionally confirm the receipt of a shipment
For legacy reasons, the project should use an existing Java "record" object and business interface. The interface essentially uses the Java record for 2 roles: the
estimate and the purchase order.
To mitigate a potentially poor design, a goal is to separate the business logic from the interface.
A high-level architect insists on using the RPC-style SOAP.
Do Try This At Home (Not in Production)
Before examining the code, note:
This example is contrived: the best practices in WS and Service Oriented Architecture mandate the publication of clean interfaces. These new, shiny interfaces hide
poorly designed code via various design patterns (e.g. adapter).
The HTTP server in Java 6 does not meet production requirements. It serves as a tool for experimentation and fast prototyping.
A Rapid Prototype

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

6 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

This example (available here) uses the same structure and Ant tasks as Example 1. The server side exists entirely in Acme.java, which we analyze here. First, the legacy
record:
class OrderRecord {
// very poor design! assume "legacy" record
// estimate fields
public int numUnits;
public String customerId;
public float cost;
// order fields
public String orderCode;
public Date expectedArrival;
}
Here is the legacy interface, decorated with JSR 181 meta-data:
@WebService (
name="AcmeWebOrderInterface"
)
@SOAPBinding(style=SOAPBinding.Style.RPC)
interface LegacyInterface {
@WebMethod
@WebResult(name="Estimate")
OrderRecord getEstimate( String customerId, int numUnits );
@WebMethod
boolean placeOrder( @WebParam(mode=WebParam.Mode.INOUT)
Holder<OrderRecord> orderHolder );
@WebMethod
@Oneway
void confirmReceipt(String orderCode);
}
Recall in JAX-WS terminology, this interface is a Service Endpoint Interface (SEI). Note the following points:
The @WebService annotation overrides the name of the web service, as we don't want a legacy name to be published. Also, @SOAPBinding is overridden to be RPC
style.
The getEstimate method returns an OrderRecord, but we override the name to be "Estimate" in the WSDL.
The placeOrder uses an INOUT parameter: the OrderRecord comes in with populated "estimate" fields and should leave with all fields populated. Note that JAX-WS
enables INOUT params with the Holder<T> class.
@Oneway adds the self-titled semantic to the confirmReceipt method, as it consists of one input and neither output nor inout elements.
A stated goal of JSR 181 is to separate public contracts from private implementations; this dovetails with an Acme requirement. The following Service Implementation Bean
(SIB) demonstrates this:
// Note that this SIB defers meta-data information to the SEI
@WebService(
endpointInterface="com.ociweb.demo.LegacyInterface",
serviceName="AcmeWebService",
portName="AcmeWebOrderPort"
)
public class Acme implements LegacyInterface {
public OrderRecord getEstimate( String customerId, int numUnits ) {
OrderRecord record = new OrderRecord();
System.out.println("received estimate request. customerId = " + customerId);
record.numUnits = numUnits;
record.customerId = customerId;
record.cost = numUnits * 100.0f;
return record;
}
public boolean placeOrder( Holder<OrderRecord> orderHolder ) {
OrderRecord order = orderHolder.value;
final int arbitraryLimit = 10000;
int randomInt = (new Random()).nextInt(arbitraryLimit);
order.orderCode = Integer.toString(randomInt);
order.expectedArrival = new Date();
System.out.println("placing order with orderCode = " + order.orderCode);
return true;
}
public void confirmReceipt(String orderCode) {
// oneway methods should generally spawn a thread to do
// the business logic
System.out.println("writing confirmation to DB for: " + orderCode);
}
// arbitrary unit-test method -- not exposed to the web service
boolean testingMethod() { return true; }
}

Note the following points:


The @WebService annotation overrides names but also ties the SIB to the SEI with the endpointInterface element. Note the separation: there are no other
annotations in this class!
The getEstimate method is straight-forward.
The placeOrder method illustrates the use of the Holder<T> class for INOUT parameters.
The spec recommendation for oneway methods such as confirmReceipt is to delegate the business logic to a separate thread.
To emphasize the separation between the SEI and SIB, the testingMethod might be used to unit-test the business logic. Note that if this method were in the
interface, it could be excluded via an element on the @WebMethod annotation.

10-Jun-16 11:49 AM

SETT June 2007 - JSR 181: a Java Simplification Request

7 of 7

http://jnb.ociweb.com/jnb/jnbJun2007.html

That's it for the server! The client steps through the use case of getting an estimate, making an order and confirming receipt. As with Example 1, JSR 181 and JAX-WS
perform an astounding amount of heavy lifting.

In Production
As noted, the HTTP server in JDK 6 is not appropriate for production. In order to move Example 2 to a production enviroment, it is necessary to use a web/app server that
is enabled for JAX-WS. Here is a list of suitable application servers which are Java EE 5 compatible (and thus JAX-WS enabled). Note that Tomcat does not yet work out-ofthe-box: here are instructions to enable Tomcat for JAX-WS.
Even with the appropriate server, another aspect to consider is the generation of the JSR-109 deployment descriptors, especially as this is the major boon of JAX-WS. The
wsgen tool (here) performs this task: it accepts a SEI and generates the required artifacts for deployment and invocation.

JAX-WS RI
The reference implemenation (RI) for JAX-WS is located here. Here is a quick road-map regarding the RI:
Version 2.0 is bundled with Java 6, but exists as a separate download for Java 5. (Strictly speaking, it requires only the annotation support in Java 5.)
Version 2.0.1 existed only as an intermediate version to transition to version 2.1. However, due to a technical issue, version 2.1 required changes to the API and spec,
and is no longer available. At this writing, version 2.1.1 is the most current release.
Some highlights of new features in version 2.1.1:
Ant and Maven support for wsimport and wsgen tools.
Support for standards such as SOAP 1.2 and WS-I Basic Profile 1.1.
Extension support for the WS-* specs within the WSIT umbrella.

Summary
Java 5's original annotation facility was not a solution, but a promise. Eventually, the solutions poured in for EJB3, JAXB and other communities within Java.
Now, JAX-WS brings the same power of development time metadata to the WS space, leveraging annotations and JAXB. Moreover, JSR 181 acts as a facade pattern for
JAX-WS and brings remarkable simplicity for common WS tasks. Combined with the innate HTTP server in Java 6, WS developers finally enjoy simplicity and agility. The
woeful cry of a "Java Simplification Request" may well soar into a joyful (if grammatically incorrect) cheer: "we never met a data we didn't like!"

Example Notes
The examples in this article use Java 1.6.0, and Ant 1.6.x. It is assumed that Java and Ant are installed on the machine. The first example is inspired by a blog post by
Vivek Pandey.

References and Resources


Java SE6
JSR 181 - Web Service Metadata for the Java Platform
JSR 224 - Java API for XML-Based Web Services (JAX-WS) 2.0
The JAX-WS Reference Implementation (RI)
JSR 101 - Java APIs for XML based RPC (JAX-RPC)
JSR 109 - Implementing Enterprise Web Services
JSR 222 - Java Architecture for XML Binding (JAXB) 2.0
JSR 175 - A Metadata Facility for the Java Programming Language
Doug Kohlert's JAX-WS blog (tech lead for spec)
Vivek Pandey's JAX-WS blog
Sun site: Developing Web Services at a Glance
SOA Using Java Web Services
SOAP (Wikipedia)
WSDL (Wikipedia)
Michael Easter thanks Eric Burke, Tom Wheeler, Dean Wette and Jeremy Ford for reviewing this article and providing useful suggestions.
The Software Engineering Tech Trends is a monthly newsletter. The purpose and intent of this publication is to advance and inform emerging trends in software
engineering.
Subscribe | Unsubscribe
OCI partners with clients to assess, design, architect, engineer, manage and support Mission-Critical, High Performance and Real Time systems. Our goal is to make IT
solutions more open, scalable, reusable, interoperable, and affordable. Please visit www.ociweb.com to learn more about our service offerings, open source middleware
technologies, and professional IT training.
OCI is a proud member of the Object Management Group, OMG.
Inquiries regarding Career Opportunities may be directed to: hr@ociweb.com.
OCI | 12140 Woodcrest Executive Drive, Suite 250 Saint Louis, MO 63141 | (314) 579-0066 | info@ociweb.com
Copyright Object Computing, Inc. 1993, 2015. All rights reserved

10-Jun-16 11:49 AM

Anda mungkin juga menyukai