- Why Not Code First?
- "Contract First" - What is So Special About It?
- Axis2 Code-Generation Tool
- A Word About the Axis2 Service Deployment Model
- First Round - Use the Default Opti ons
- Second Round - Use a Different Databinding
- Third Round - Generate an Interface Instead of a Concrete Class
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 thecontract 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 theaar file, which is an archive file that contains all the artifacts required by the service. (AAR stands forAxis2 ARchive.) The content of the aar file has the structure shown in Figure 1.
The services.xml that goes inside the META-INFdirectory 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
--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:
- src directory
- 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 aarfile. The skeleton will be namedCurrencyConverterServiceSkeleton 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:
After a successful build, one more directory will be generated named build. The build directory contains a libdirectory 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 aarfiles 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 srcdirectories. In this case, the XMLBeans-specific binary file set (with the extension xsb) will be available in theresources 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 theaar 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.
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.
- Eclipse WTP - a tool that allows easy WSDL creation
- currencyConvert.wsdl- used for the examples in this article
- Sample code for this article
- Axis2 standard binary distribution (ZIP, 10.3 MB)
- The official Axis 2 site
- Understanding Axis2 Deployment Architecture - an article on Axis deployment mechanism< that explains the aar file format
- Axis2 based public Tungsten servers