Skip to main content

Contract-First Web Services with Apache Axis2

August 8, 2006

{cs.r.title}






When implementing Web services, there are two alternative
development paths you can take: the code-first approach and
the contract-first approach. This article drills down into
the contract-first approach in detail and shows how the Axis2 code generator can be used
to generate code for the server side with the contract-first
approach.

Why Not Code First?

Usually when developing Web services, developers like to code
the business logic first and then expose that logic as a Web service.
This is convenient because developers' core competency is the particular programming language they use. It also happens to be much
more convenient for exposing existing programs as Web services.
However, the code-first approach has several drawbacks.

  • The developer has less control over the process of exposing
    code as services. A change to the code may mean a regeneration of
    the publicly visible Web services interfaces, and often it is
    difficult to agree on such a generated interface from a business
    perspective. The client programs often are generated using the
    service's WSDL file; if the service WSDL file is likely to
    change, then the point of having generated clients becomes less
    obvious.

  • The code for the service process is likely to change between
    service frameworks and even framework versions, and it becomes
    difficult to maintain a single interface across versions.

It is true that by using annotations the impact of some of these
issues can be lessened. Annotations help the developer take
control of the process of exposing code. However, there is no such
thing as a generic annotation scheme to make it universally
applicable over multiple languages and multiple frameworks!

"Contract First" - What is So Special About It?

As opposed to code first, the contract-first approach takes the
contract as the primary artifact. The "contract" in a Web
service interaction obviously is the WSDL document; therefore, in the
contract-first approach, the focus is on creating the WSDL file and
the associated XML schema. The WSDL file and the schema clearly
define the message formats, the operation and interface names, and
other relevant information for a complete Web service interaction,
and can be agreed on by multiple parties. Almost all major Web
service frameworks allow service generation from WSDLs, and it
becomes easier for the service implementer too; because the major
portion of the code is generated, only the necessary business logic
would need to be filled in.

It should be noted that the contract-first approach has its own
problems, the most notable one being the need for WSDL and
schema expertise. One can argue whether the Web service
implementers would need to do anything with WSDL since the primary
requirement of the WSDL is in providing a description of the
service rather than providing the service itself. This would have been a
major problem in earlier times, but now some very good visual
tools are available, both free and commercial, allowing easy construction of
WSDLs. The Resources section provides links to
one such free WSDL editor.

The next section of this article shows how to utilize Axis2 to
build Web service implementations with a contract-first
approach.

Axis2 Code-Generation Tool

The Apache Axis2 project comes bundled with a new code-generator tool. This code generator allows multiple data-binding frameworks to be incorporated and is easily extendable.

In its simplest form, the code generator is a command-line tool.
It also comes in other flavors like the Eclipse/IDEA plug-in or the
custom ant task. However, these use the same tool
core to generate code and the options available are the same. All
the examples in this article use the command-line tool, but the
graphical equivalent is easy to figure out and can be used
appropriately.

The batch/shell scripts for the code-generator tool are
available in the bin directory of the
Axis2 standard binary distribution
(ZIP, 10.3 MB). Usually,
once the standard Axis2 distribution is downloaded and unzipped,
the scripts are ready for action. If you are having problems
running the tools, the Axis2 site has a great deal of documentation
for how to install Axis2, set up the classpath, and more.

A Word About the Axis2 Service Deployment Model

The Axis2 service deployment model is drastically different from
the older deployment models, and is worth mentioning before diving
down into the details. The primary concept of Axis2 is the
aar file, which is an archive file that contains all the
artifacts required by the service. (AAR stands for
Axis2 ARchive.) The content of
the aar file has the structure shown in Figure 1.

aar format
Figure 1. Structure of an AAR file

The services.xml that goes inside the META-INF
directory is the primary controller of the service. It specifies
the artifacts to load and the parameters for each artifact. More
information about aar files can be found on the Axis2 Web
site, and the Resources section includes
links to more information about the Axis2 deployment mechanism.

Enough said. It is time to dig in!

First Round - Use the Default Options

To generate server-side code from a WSDL, you have to provide the
-ss (short for --server-side) and
-sd (--service-descriptor) flags to the
code generator. Really it is the -ss flag that
determines whether it is server-side code, but it is recommended
that the -sd flag also be used with the
-ss flag, since the service cannot be deployed without
a service descriptor.

The following command generates server-side code with default
options:

> WSDL2Java -uri currencyConvert.wsdl -ss -sd

Since no output location has been specified, the output will be
directed to the current directory. The default data binding
mechanism is ADB (Axis
Data Binding).

Three artifacts will be visible immediately after the code
generation:

  1. build.xml
  2. src directory
  3. resources directory

Inside the src directory, the source files will be
available inside the org/apache/axis2 directory since it
takes the default package when not specified. The most interesting
item here is the generated skeleton. This skeleton is meant for the
service implementer to be filled in and is the only piece
of code that would need to be modified to have a successful
service.

The resources directory will contain two files: the WSDL
file for the service and the services.xml file. These files
need to go into the META-INF directory of the aar file. The
skeleton will be named CurrencyConverterServiceSkeleton to
match the service name. For each operation in the
WSDL a corresponding method will be generated in the skeleton
class.

The following code snippet shows an example implementation of
the skeleton:

com.examplewebservice.www.types.ConversionResponse res = new 
    com.examplewebservice.www.types.ConversionResponse();

//do a proper calculation here
//right now we pick an arbitrary number to multiply with

res.setAmount(param0.getAmount()*102.32f);
return res;

Note that this code goes inside the skeleton
method.

Once the skeleton is implemented, the recommended way to
generate the service archive is to use the Ant build file. While it
is certainly possible to do the archive creation manually, the Ant
build is very convenient and saves developers a lot of trouble.

Run the Ant build file by typing ant. Note
that you have to have the AXIS2_HOME environment
variable set to point to the Axis2 installation location for the
Ant build to succeed:

> ant

After a successful build, one more directory will be
generated named build. The build directory contains a
lib directory that contains the generated aar file.

As a quick way of testing the service, the archive can be
uploaded to one of the open WSO2 Tungsten servers available
at tools.wso2.net.
WSO2 Tungsten is a bundled version of Axis2, and Axis2 aar files
are fully compatible with WSO2 Tungsten.

Second Round - Use a Different Databinding

Axis2 allows use of different data-binding frameworks for code
generation, and for this round we'll try to use XMLBeans.

The following command generates server-side code, using XMLbeans
for the databinding. Note that the earlier generated artifacts (if
they are still there) need to be manually removed, since the code
generator does not overwrite existing files:

> WSDL2Java -uri currencyConvert.wsdl -ss -sd -d xmlbeans

The immediately noticeable changes among the artifacts is the
presence of some more files in the resources and src
directories. In this case, the XMLBeans-specific binary file set
(with the extension xsb) will be available in the
resources directory.

The skeleton is very similar to the one in case 1, except
it has XMLBeans-specific classes in the skeleton rather than the
ADB classes. The following code snippet shows how the skeleton can
be filled using XMLBeans data-bound classes:

com.examplewebservice.www.types.ConversionResponseDocument  res =
    com.examplewebservice.www.types.ConversionResponseDocument.
        Factory.newInstance();
  //do a proper calculation here
  //right now we pick an arbitrary number to multiply with
  res.setAmount(param0.getAmount()*102.32f);
  return res;

You can see that the skeletons have a strong resemblance to
each other even though the underlying databinding mechanism has
changed completely. All the issues related to databinding are
handled under the hood, and the service implementation would not
need to worry about anything other than filling in the business
logic.

The importance of using the Ant build file for making the aar
file becomes clear when using XMLBeans. The XMLBeans databound
classes do require the .xsb files to be in the classpath, and
the generated Ant build comes with targets that copy these
non-class files to the appropriate locations.

Third Round - Generate an Interface Instead of a Concrete
Class

A common (and reasonable) requirement of the service developers
is to have an interface for the skeleton and then name a particular
service implementation for the configuration. This can easily be
done with Axis2 by using the -ssi (server-side
interface) flag:

> WSDL2Java -uri currencyConvert.wsdl -ss -sd -ssi

This code causes the emitter to emit an interface in place of a
concrete class. Of course, the concrete class is also generated,
but it is not referred to inside the message receiver. Instead, the
interface is used, and the user is free to place any class that
implements that interface as the service class.

One other interesting tweak to the code generation is generating
both server-side and client-side code in a single shot. This can be
achieved using the -g flag. The generated code will contain
both the skeleton and the stub and will be of use when code
generating everything at once!

The code generator provides a number of options for tweaking the
generated code, and the complete reference is available
on the Axis2 site
.

Conclusion

The contract-first approach is the better way to go when it
comes to implementing Web services. Fortunately, Axis2 has a
flexible code generator that supports first-hand contract-first
development.

Resources

width="1" height="1" border="0" alt=" " />
Ajith Ranabahu is one of the principal architects of the Axis2 project and specializes in the ADB and codegen modules.
Related Topics >> Web Services and XML   |