Sunday, January 22, 2012

JAX-WS processing using Axis2 tools

JAX-WS wsgen and wsimport tools were designed to generate portable artifacts so that those artifacts can be use with any JAX-WS vendor runtime also these tools distribute as a part of JDK. Traditionally Axis2 does not provide any JAX-WS tools, instead it's possible to execute artifacts generated by wsgen and wsimport tools within Axis2. Recently number of users are requested to enable JAX-WS processing through Axis2 tools such as WSDL2JAVA and JAVA2WSDL. Starting from 1.7.0 version Axis2 provides first class JAX-WS processing support for both WSDL2JAVA and JAVA2WSDL tools. Also it's possible use  wsgen and wsimport tools with Axis2 in the usual manner.  


There is a new command line option introduced as "jws" that enables switching between Axis2 native processing and JAX-WS processing. Once the "jws" option available the tool will switch to JAX-WS processing from default Axis2 native processing . 

To provide other input options it is possible to use some of the existing WSDL2JAVA/JAVA2WSDL options or possible to use  wsgen/wsimport options if those option names are not conflict with Axis2 tools option names. If such option name conflict occurs Axis2 option will get the priority.

WSDL2JAVA options


























Option (Axis2) Option (wsimport)
-uri [url or path] -uri [url or path] A url or path to a WSDL
-o [path] -d [path] Specify a directory path for the generated code
-p [pkg name] -p [pkg name] Specify a custom package name for the generated code
-http-proxy-host [host name] -httpproxy [host:port] specify a HTTP proxy server
-http-proxy-port [port]


Examples :
 wsdl2java.sh -jws -uri SimpleService.wsdl   

 wsdl2java.sh -jws -uri SimpleService.wsdl -o out  

 wsdl2java.sh -jws -uri SimpleService.wsdl -d out  


JAVA2WSDL options






  
















Option (Axis2) Option (wsimport)
-cn [fully qualified class name] -cn [fully qualified class name] fully qualified class name
-o [path] -d [path] Output directory
-cp [class path uri] -cp [class path uri] list of classpath entries


 Examples :
 java2wsdl.sh -jws -cn sample.UserService 

 java2wsdl.sh -jws -cn sample.UserService -d out  

 java2wsdl.sh -jws -cn sample.UserService -o out  

Friday, January 20, 2012

Axis2 Simple HTTP server Maven plugin

As I mentioned in my last blog post this post covers one of the new feature of upcoming Axis2 1.7.0 version. Recently we have done number of improvements for Axis2 Maven support. There are three new Maven related modules introduced as follows.
  1.  simple-server-maven-plugin - A Maven plug-in that allows to run Axis2's simple HTTP server as a maven plug-in.
  2. quickstart archetype - Maven archetype to develop and package Axis2 native (AAR) web services.
  3. quickstart-webapp - Maven archetype to develop and package Axis2 web services as a web application(WAR).  
In this post I discuss how to use  simple-server-maven-plugin and it's configuration options. At the moment simple-server-maven-plugin provides  single goal as "axis2:run".

You can add simple-server-maven-plugin into your Maven POM file as follows.

     <plugin>  
         <groupId>org.apache.axis2</groupId>  
         <artifactId>simple-server-maven-plugin</artifactId>  
         <version>${axis2.version}</version>  
     </plugin>  

Note : At the moment this plug-in available only with 1.7.0-SNAPSHOT version and until this get released with official Apache releases you have to do one extra step as mentioned here[1].

As you may know Axis2 services expect single meta data file called services.xml under a directory named META-INF. By default it expect to place this meta data files under the "src/main/resources/services" directory. In order to deploy multiple service META-INF should place inside a another directory. As an example /src/main/resources/services/SimpleService/META-INF/services.xml. Also by default it facilitates to place Axis2 modules (.mar) under src/main/resources/modules directory. Following picture shows one such a example directory structure.

Once you have completed above steps you can run Axis2 Simple HTTP server using run goal.

 mvn clean axis2:run  

Now It's possible to access available service listing  page by http://localhost:8080 URL.

simple-server-maven-plugin support for following configuration options.


Option
repoPath Path to Axis2 repository by default run goal creates Axis2 repository inside the project's target directory.
confPath Path to Axis2.xml configuration file.
stdServiceSrcDir Directory to place service meta (META-INF/services.xml) information. This directory supports multiple service deployment. Default value is "src/main/resources/services".
moduleSrcDir moduleSrcDir - Directory to place Axis2 modules (.mar) default value is "src/main/resources/modules"

Hope this plug-in save web service development time greatly and also this can be used to automate unit test easily. 




[1] - Since above plug-in still not available on official Maven repositories  it is required to add following SNAPSHOT repository to your POM file. But this is not required after Axis2 1.7.0 release.
    <pluginRepositories>  
           <pluginRepository>     
            <id>apache-snapshots</id>     
            <url>http://repository.apache.org/snapshots</url>  
           </pluginRepository>    
      </pluginRepositories>  





Wednesday, November 16, 2011

What is new in Axis2 1.7.0 - 1

I conducted a Fast Feather talk during the ApacheCon NA 2011 to give a overview about new features of upcoming Axis2 1.7.0 release. I started to write series of blog post mentioning new features of new release I will explain each of these features in detail and try to provide samples too.

As the starting post I attached a slide that shows overview of most of the new features.    


Thursday, October 20, 2011

SOAP encoding and Axis2

As of today SOAP encoding only exists due to some historical reasons non of the standard web service framework supports for SAOP encoding that includes Axis2, Metro and CXF. Some people still tend to use SAOP encoding without knowing why WS frameworks discourage to use it or some have to use it when they implement web service clients. Usually I can see number of such queries on axis2-user list time to time. Here I discuss few workarounds useful when you dealing with SAOP encoding.


What is SOAP encoding

When authors of SOAP specification write it for first time they wanted to define a common way to describe messages but at that time XMLSchema was not completed and not in main stream too. Hence they came up with idea of SOAP Encoding as an extension of the SOAP specification that defines how a data value should be encoded in an XML.

SOAP encoding define it's own namespace as http://schemas.xmlsoap.org/soap/encoding/ and set of rules to follow. SOAP encoding introduced number of interoperability and validation issues. Tim Ewald described some of those issues in his article here.WS-I also highly discourage to use encoding systems in their basic profile.


SAOP encoding in server side

If you use code first approach there is nothing to worry Axis2 runtime generate WSDL that does not use SOAP encoding at all. But if you use contract first approach you need to make sure that you don't use SOAP encoding in your service contract instead XMLSchema provides very powerful type system for your messages.

SOAP encoding array concept is still used by many people, if you have such legacy WSDL file you could easily redesign your types using XMLSchema. Following example describes one such scenario.


First let's see SAOP encoding sample.

 <complexType name="ArrayOfStrings">  
  <complexContent>  
   <restriction base="SOAP-ENC:Array">  
    <attribute ref="SOAP-ENC:arrayType"  
          wsdl:arrayType="xsd:string[]"/>  
   </restriction>  
  </complexContent>  
 </complexType>  


Now same thing can be easily rewritten using XMLSchema as follows.

 <complexType name="ArrayOfStrings"  
  <element name="item" type="xsd:string" maxOccurs="20"/>  
 </complexType>  


SOAP encoding in client side

Sometimes it is required to access services that has service description with SOAP encoding constructs. By default Axis2 code generation tool called WSDL2JAVA fail on generating codes for such WSDL files. But as a workaround you could use XMLBeans data binding to generate clients codes for above WSDLs. XMLBeans simply generate Java beans for all the types available on schema . In this case it generate beans for all the types available on SOAP encoding schema here.

You can invoke code generation tool with XMLbeans data binding as follows.

 wsdl2java.sh -uri service.wsdl -d xmlbeans   


Conclusion

As we discussed the best practice is avoid use of SOAP encoding when you design web services.In case if you are a consumer of service that use SAOP encoding in their WSDL, Axis2 XMLBeans data binding provide a great solution for you.

Sunday, September 11, 2011

Apache Community building event within WSO2Con 2011

We are planning to have a free Apache Community building event within
the WSO2Con conference next week (13th September to 15th September) in
Colombo, Sri Lanka. We would like to invite contributors /committers
on Apache Axis2, Apache WS, Apache ODE, Apache Synapse to take a part
of this event. Number of committers from above projects will be there
and it's a good chance to communicate with them and get your first
step on those mentioned projects.  Also you can join with us using any
Freenode  IRC client on #axis2 channel or use #Axis2 on Twitter.


This Community event sponsored by WSO2 and will be held on same conference venue. WSO2 is a leading and long-standing contributor of number of world class Apache projects that includes Axis2 , Synapse, WS, Woden etc.  Most of WSO2 committers will participate to this event and it's a rear chance to meet them face to face and discuss your issues , suggestions  etc. Also those who want to contribute  also can get their hands dirty with those project's first step. No one can tell, isn't it your first step to be a Apache committer ? you better give a try and see .

you can find location and other details from here http://wso2.com/events/wso2con-2011-colombo/

One last thing , within WSO2 we not only develop and release products under Apache licence instead we use Apache like open development model, WSO2 engineering lists are completely open for anyone and we are encouraging community contribution.

Sunday, July 31, 2011

How to get best use of AXIS2 Object support.


Axis2 web service framework offers number of development approaches to match various user requirements instead of limiting to support one or two specifications. This is a one distinct feature that Axis2 go beyond from some other web service frameworks. If someone want to deploy a web service very quickly using POJOs without touching XML or SOAP, AXIS2 ADB is the ideal solution for him. ADB Object support is a one of the great feature and we have done some nice set of recent improvements too. I will discuss few tips within this post that users should know in order to get best use of Axis2 ADB Object support.

 Public Object objectService(Object obj){  
 System.out.println(obj)  
 return obj;  
 }  

Since above method takes Object type as an argument and return type it should possible to send any java primitive or POJO as a parameter value. As an example for a sample String massage it is possible to have following payload.

 <ns2:obj   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
           xmlns:xs="http://www.w3.org/2001/XMLSchema"   
           xsi:type="xs:string">  
        Hello World  
 </ns2:obj>  


In case of POJO message it is possible to have following payload.

 <ns2:obj xmlns:ns1="http://sample/xsd"   
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
                 xsi:type="ns1:Student">  
             <ns1:age>20</ns1:age>  
             <ns1:id>200</ns1:id>  
             <ns1:name>saman</ns1:name>  
            </ns2:obj>  


In above messages “xsi:type” attribute carries type system information that is required in marshalling and unmarshalling. When you send a POJO value server need to aware with the schema information associate with that particular POJO type otherwise marshalling/unmarshalling process will not possible. Typically Axis2 run-time only aware with the types associate with a particular service method, if you send above second message you will get an exception something similar to below because server can’t identify type system associate with incoming message.
 Exception in thread "main" org.apache.axis2.AxisFault: Unknow type {http://sample/xsd}Student  

the solution here is use a parameter called “extraClass” within your services.xml file.

e.g -

 <parameter name="extraClass">sample.Item,sample.Student</parameter>  

The above parameter will instruct run-time to register type details of give classes and generate schema as well . Without schema generation it is not possible to write WS clients that capable of send and receive messages with above POJOs. That is what you all need in server side now you can test your service using a tool like SoapUI.


In client side easiest and quickest way to write a client is generate code using WSDL2JAVA tool , again by default WSDL2JAVA tool also ignore extra sachem type available on WSDL file when generating codes. But it is possible to change this behaviour by adding option
“-g” that instruct to generate codes for all the schema types available . You can use following command to generate client side codes for sample application .

 axis2-1.7.0-SNAPSHOT/bin/wsdl2java.sh -uri http://localhost:8080/services/SimpleObjectService?wsdl -g   

Now you have generated POJOs in your client side you can use them with your Object service as follows.
 Student student = new Student();  
 student.setName("saman");  
 student.setId(200);  
 student.setAge(20);  
 req.setObj(student);  
 ObjectServiceResponse res = stub.objectService(req );  
 System.out.println(res.get_return());  

Tuesday, July 26, 2011

W3C Document support in Axis2



Recently we have implemented W3C Document  support for Axis2 ADB data binding. Now it is possible to use W3C Dom Document  as a input parameter , return type or as a field of a java bean. 
Let’s consider following web service method as an example. 
 public Document simpleDomService(Document doc) {  
    printInCommingDocument(doc);  
    return doc;  
  }  
It takes W3C DOM Document  as a parameter and return the same value. In order to support this method Axis2 run time should construct DOM Document from incoming payload and need to be serialized into out going payload in both server and client sides. 
In server side  based on Java refection Axis2 run-time identify parameters and return type of DOM Document and perform required conventions. But in client side this become bit of a complex task because they is no standard  way  to represent DOM Document in a WSDL. Axis2  generate xs:any type for DOM Document and this is represented as a OMElement  in generated code.
With above limitation if you have a Dom Document first you need to convert into a OMElement , you could use following code segment to convert DOM to OM. 

 OMFactory fac = OMAbstractFactory.getOMFactory();  
 OMElement domDoc = BeanUtil.convertDOMtoOM(fac, getDomDocument()); 
 
The other option is without constructing a DOM Document, directly construct a OMElement and pass it to the server side. If the server side method parameter type is DOM Document  Axis2 run-time can construct  a DOM Document for that particular service. As an example following code segment use String to construct OMElement. Refer Axiom user guide to find out other options.  
 public static OMElement getOmDocument() throws XMLStreamException {  
    return AXIOMUtil  
        .stringToOM("sample content using Axiom");  
  }  
After a successful invocation you receive a OMElement as the return value , sometimes you may want to convert this incoming value in to a DOM back . In such scenarios following code segment can be used. 

 public static org.w3c.dom.Document getDomDocument(OMElement element){  
    OMFactory doomFactory = DOOMAbstractFactory.getOMFactory();  
    StAXOMBuilder doomBuilder = new StAXOMBuilder(doomFactory,  
        element.getXMLStreamReader());  
    return (org.w3c.dom.Document) doomBuilder.getDocument();  
  }  

Here is the complete  client side code 

     // create a OMElement using Axiom tools.  
     OMFactory fac = OMAbstractFactory.getOMFactory();  
     OMElement domDoc = BeanUtil.convertDOMtoOM(fac, getDomDocument());  
     // create a pure Axiom based document  
     OMElement omDoc = getOmDocument();      
     SimpleDomServiceStub stub = new SimpleDomServiceStub();  
     SimpleDomService req = new SimpleDomService();  
     Document doc = new Document();  
     req.setDoc(doc);  
     //1st call  
     doc.setExtraElement(domDoc);  
     SimpleDomServiceResponse res = stub.simpleDomService(req);  
     res.get_return().getExtraElement().serialize(System.out);  
     //2nd call  
     System.out.println();  
     doc.setExtraElement(omDoc);  
     res = stub.simpleDomService(req);  
     res.get_return().getExtraElement().serialize(System.out);  

Note : 
1.) Some of above features based on Axiom based DOM API implementation called DOOM. But DOOM is not a complete implementation of W3C DOM and you may find some limitation. 
2.) Above features available with  upcoming   Axis2 1.7.0 release and right now you can try with 1.7.0-SNAPSHOT.
3.) Download sample project from here.  You can run “mvn jetty:run “ to start embedded Jetty server and WSDL content can be found here http://localhost:8080/services/SimpleDomService?wsdl.