Pages

Wednesday, March 28, 2007

Step by step tutorial to use Rampart with axis2 web service for implementing security.

Given below is a tutorial to use axis2 in implementing web services with security(This shows sync/Blocking call client along with Rampart security). This tutorial extends the previous tutorials to add security features to the web services using rampart module. For more details regarding any aspect of the tutorial, the axis2 or rampart documents will assist you.

My Configuration:(same as previous)
a) AXIS2 1.1.1
b) JDK 1.5
c) ANT 1.7.0
d) TOMCAT 5.5

Before proceeding, please read the installation doc of axis2 and rampart to do a proper installation.

Step 0: Set the following paths in your system.(This step is very important)
a) AXIS2_HOME = "your axis2 installation(unzipped) directory"
b) JAVA_HOME = "your jdk installation path"
c) PATH = "add ant, axis2/bin to this"

Step 1: Extract the rampart-1.1.zip. Before doing anything more copy the %AXIS2_HOME%/lib to %AXIS2_HOME%/lib.1. Run the ant task on build.xml present in extracted folder. Now rebuild the whole axis2(i.e run the ant task in %AXIS2_HOME%/webapp). Deploy this in your server. Rename the lib to lib.2, and lib.1 to lib.[This is to run WSDL2JAVA and JAVA2WSDL tool, other wise the tools doesn't run and the reason is that the path AXIS2_CLASS_PATH becomes too long(I am running on Win 2000)]

Step 2: Create your service interface and impl class. Generate the WSDL using java2wsdl, generate the skeleton and stubs using wsdl2java, code the skeleton. Build the "MyRampartService.aar" and deploy on the server. Test the service. Use the client service stub to code a basic client, run the client to see its working. This step has set up a web service and a client in a usable state. Next, step goes through the rampart part.
The service and skeleton are given below for reference.
--------------Interface-------------------
package axis2.adb.sync.rampart;
public interface MyRampartService {
public String getSecretText(String codeword);
}

-------------Impl class-------------------
package axis2.adb.sync.rampart;
public class MyRampartServiceImpl implements MyRampartService {
public String getSecretText(String codeword) {
if(codeword.equalsIgnoreCase("apache"))
return "You have done a good choice to build an application";
return "You have done a bad choice to build application";
}
}
-------------Skeleton Class----------------
/**
* MyRampartServiceSkeleton.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 1.1.1 Jan 09, 2007 (06:20:51 LKT)
*/
package axis2.adb.sync.rampart;
import axis2.adb.sync.rampart.MyRampartService;
import axis2.adb.sync.rampart.MyRampartServiceImpl;
import axis2.adb.sync.rampart.xsd.GetSecretTextResponse;
public class MyRampartServiceSkeleton implements MyRampartServiceSkeletonInterface {
MyRampartService myService = new MyRampartServiceImpl();
public axis2.adb.sync.rampart.xsd.GetSecretTextResponse getSecretText(axis2.adb.sync.rampart.xsd.GetSecretText param2){
GetSecretTextResponse res = new GetSecretTextResponse();
res.set_return(myService.getSecretText(param2.getParam0()));
return res;
}
}

Step 3: This step uses the example from the rampart sample05. The intention is to encrypt the data in XML's which are exchanged between the client and the server. Copy %AXIS2_HOME%/repository to a convenient location. Copy %AXIS2_HOME%/conf/axis2.xml to %COPIED_LOCATION%/repository/modules/client.axis2.xml. Copy the rampart-1.1/samples/Keys to "resources" directory created on running the WSDL2JAVA on previous step. We will be using the same keystore which rampart has provided for encrypting the message. you use the "keytool" that is a part of JDK to create your own keystore. Add the rampart lib also to your classpath to compile and run the client. Copy from the sample05 directory org/apache/rampart/samples/sample05/PWCBHandler.java into your source directory(remember to change the package in PWCBHandler.java, if you put it in some other package). This is the callback handler that is called on the client and the server side for verifying the password.

Step 4: Modify the resources/services.xml and %COPIED_LOCATION%/repository/modules/client.axis2.xml to enter Rampart configuration.
Add the below into the services.xml.
<serviceGroup>
<service name="MyRampartService">
......
......
<module ref="rampart" />
<parameter name="InflowSecurity">
<action>
<items>Encrypt</items>
<passwordCallbackClass>axis2.adb.sync.rampart.callbackhandler.PWCBHandler</passwordCallbackClass>
<decryptionPropFile>service.properties</decryptionPropFile>
</action>
</parameter>

<parameter name="OutflowSecurity">
<action>
<items>Encrypt</items>
<encryptionUser>client</encryptionUser>
<encryptionPropFile>service.properties</encryptionPropFile>
</action>
</parameter>
</service>
</serviceGroup>

Add the below into the client.axis2.xml just before the "phases" definitions.
<module ref="rampart" />

<parameter name="OutflowSecurity">
<action>
<items>Encrypt</items>
<encryptionUser>service</encryptionUser>
<encryptionPropFile>client.properties</encryptionPropFile>
</action>
</parameter>

<parameter name="InflowSecurity">
<action>
<items>Encrypt</items>
<passwordCallbackClass>axis2.adb.sync.rampart.callbackhandler.PWCBHandler</passwordCallbackClass>
<decryptionPropFile>client.properties</decryptionPropFile>
</action>
</parameter>

Now, parameter OutFlowSecurity represents the action to be taken on the outgoing XML's. In our case it is to encrypt. The encryption property file client.properties is present in keys directory. It gives the details of the keystore file, the password to that keystore, the keystore type and the provider.

The parameter InFlowSecurity represents the action to be taken on the incoming XML's. It provides with the decryption property file which is same as the encryption property file in client.axis2.xml, the action item is same as the OutFlowSecurity action item and the password callbackhandler class. I am using the one which came with samples provided with apache rampart.Its given below.

import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class PWCBHandler implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
String id = pwcb.getIdentifer();
if("client".equals(id)) {
pwcb.setPassword("apache");
} else if("service".equals(id)) {
pwcb.setPassword("apache");
}
}
}
}

Step 5: Edit build.xml.
Search for target "jar.all" and add the following beneath the first copy element.
<copy toDir="${classes}" failonerror="false">
<fileset dir="${resources}/keys">
<include name="*.jks"/>
<include name="*.properties"/>
</fileset>
</copy>

Step 6: Build and deploy service.

Run ant command on this build.xml and deploy the service on axis2 in tomcat. Do not forget to restart the tomcat server if hotupdate is off.

Step 7: Edit the client and run. The client code is given below with appropriate comments. We do not have to configure the client using the XML, it can be done through code also. The below client uses the code when useRampartThroughCode is set to true. Please note that when this is used you do not have to configure the inflowsecurity and outflow security in the client.axis2.xml. Add the "resource/keys" on to the classpath before you run the client.

package axis2.adb.sync.rampart.client;
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.Parameter;
import org.apache.rampart.handler.WSSHandlerConstants;
import org.apache.rampart.handler.config.InflowConfiguration;
import org.apache.rampart.handler.config.OutflowConfiguration;
import axis2.adb.sync.rampart.MyRampartServiceStub;
import axis2.adb.sync.rampart.xsd.GetSecretText;
import axis2.adb.sync.rampart.xsd.GetSecretTextResponse;

public class MyRampartServiceServiceClient {
private static boolean useRampartThroughCode = false; // set this to true if you do not want to configure client using client.axis2.xml for using rampart.

public static void main(String[] args) {
MyRampartServiceStub stub = null;
ConfigurationContext configContext = null;
try {
// put your appropriate repository path in first arg, and path to client.axis2.xml in second arg.
configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("Axis2WithRampart/repository", "Axis2WithRampart/repository/modules/client.axis2.xml");
//create the stub
stub = new MyRampartServiceStub(configContext,"http://localhost:8080/axis2/services/MyRampartService");
if(useRampartThroughCode){
//set the outflow security through code
stub._getServiceClient().getOptions().setProperty(WSSHandlerConstants.OUTFLOW_SECURITY, getOutflowConfiguration());
//set the inflow security through code
stub._getServiceClient().getOptions().setProperty(WSSHandlerConstants.INFLOW_SECURITY, getInflowConfiguration());
}
// invoke the service
String returnText = getSecretTextFromRampartService(stub,"apache");
// print it out
System.out.println("Return Text: " + returnText);
} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException re){
re.printStackTrace();
}

}

private static String getSecretTextFromRampartService(MyRampartServiceStub stub, String string) throws RemoteException {
//create the request payload
GetSecretText req = new GetSecretText();
//set the parameter in the payload
req.setParam0(string);
//invoke service and get response
GetSecretTextResponse res = stub.getSecretText(req);
//return the response string.
return res.get_return();
}

private static Parameter getOutflowConfiguration() {

OutflowConfiguration ofc = new OutflowConfiguration();
//set the action item
ofc.setActionItems("Encrypt");
//set the encryption user
ofc.setEncryptionUser("service");
//set the property file; remember if the properties is not in classpath then it will not find this.
ofc.setEncryptionPropFile("client.properties");
// return the Parameter
return ofc.getProperty();
}

private static Parameter getInflowConfiguration() {
InflowConfiguration ifc = new InflowConfiguration();
//set the action item
ifc.setActionItems("Encrypt");
//set the password callback class
ifc.setPasswordCallbackClass("axis2.adb.sync.rampart.callbackhandler.PWCBHandler");
//set the property file; remember if the properties is not in classpath then it will not find this.
ifc.setDecryptionPropFile("client.properties");
//return the parameter
return ifc.getProperty();
}

}

Step 8: The output.
You will see the output:

Return Text: You have done a good choice to build an application

You can use the tcpmon tool to capture the XML exchanges. Then, you can observe the encrypted contents of the request and response messages.

NOTE: I am using the keystore's and the password callback handlers provided with rampart distribution for explaining this tutorial.

Monday, March 26, 2007

Step by step tutorial of web service with axis2 and tomcat in java - part2

Given below is a tutorial to use axis2 in implementing web services(This shows Async/Non-Blocking call client). This tutorial extends the previous tutorial of blocking client call of web service. For more details regarding any aspect of the tutorial, the axis2 documents will assist you.
(Just for Information: The web service gives the Lucky number of a person based on date of birth, and lucky color based on lucky number of user.)

My Configuration:(same as previous)
a) AXIS2 1.1.1
b) JDK 1.5
c) ANT 1.7.0
d) TOMCAT 5.5

Before proceeding, please read the installation doc of axis2 to do a proper installation.

Step 0: Set the following paths in your system.(This step is very important)
a) AXIS2_HOME = "your axis2 installation(unzipped) directory"
b) JAVA_HOME = "your jdk installation path"
c) PATH = "add ant, axis2/bin to this"

Step 1: Create your service interface and class.

In my case:
--------------Interface-------------------
package axis2.adb.async;
import java.util.Date;
public interface MyNewService {
public String getLuckyColor(int luckNumber);
public int getLuckyNumber(Date birthDate);
}
--------------Implementation--------------
package axis2.adb.async;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class MyNewServiceImpl implements MyNewService {
static Map luckyColor = null;
static{
luckyColor = new HashMap();
luckyColor.put(new Integer(0), "Red");
luckyColor.put(new Integer(1), "Blue");
luckyColor.put(new Integer(2), "Yellow");
luckyColor.put(new Integer(3), "Pink");
luckyColor.put(new Integer(4), "Orange");
luckyColor.put(new Integer(5), "Black");
luckyColor.put(new Integer(6), "Green");
luckyColor.put(new Integer(7), "Brown");
luckyColor.put(new Integer(8), "White");
luckyColor.put(new Integer(9), "Grey");
}
public String getLuckyColor(int luckNumber) {
if(luckNumber < number =" birthDate.getDate()" lucknumber =" 0;"> 0){
luckNumber += number % 10;
number /= 10;
if(number == 0)
if(luckNumber > 9){
number = luckNumber;
luckNumber = 0;
}

}
return luckNumber;
}
}

Step 2: Generate the WSDL file using the command:
java2wsdl -cp ./bin -cn axis2.adb.async.MyNewService -of ./resource/MyNewService.wsdl
See the previous tutorial for more explanation.

Step 3: Generate the Skeleton and stub using the below command. I will be using the ADB(Axis data binding). You can use XMLBean or JiBx or AXIOM also.

wsdl2java -uri ./resource/MyNewService.wsdl -p axis2.adb.async -d adb -a -ss -sd -ssi -g -o . -S axis2ADBAsync
Here, the changes from the previous tutorial include:
a)-a switch instead of -s. -a is used for Async web Service.
b)-g switch generates the Client side stub along with the Skeleton.
c)-S switch allows you to provide the output folder

Step 4: Put the business logic inside the skeleton. The code is explained with appropriate comments.

package axis2.adb.async;
import java.util.Calendar;
import axis2.adb.async.MyNewService;
import axis2.adb.async.MyNewServiceImpl;
import axis2.adb.async.xsd.GetLuckyColorResponse;
import axis2.adb.async.xsd.GetLuckyNumberResponse;
/**
* MyNewServiceSkeleton java skeleton for the axisService
*/
public class MyNewServiceSkeleton implements MyNewServiceSkeletonInterface {
MyNewService myService = new MyNewServiceImpl();
/**
* Auto generated method signature
*
* @param param4
*
*/
public axis2.adb.async.xsd.GetLuckyColorResponse getLuckyColor(
axis2.adb.async.xsd.GetLuckyColor param4)
{
//create the response payload
GetLuckyColorResponse res = new GetLuckyColorResponse();
//get the parameter
int luckyNumber = param4.getParam0();
//businesslogic
String luckyColor = myService.getLuckyColor(luckyNumber);
//put result in payload
res.set_return(luckyColor);
//return payload
return res;
}

/**
* Auto generated method signature
*
* @param param6
*
*/
public axis2.adb.async.xsd.GetLuckyNumberResponse getLuckyNumber(
axis2.adb.async.xsd.GetLuckyNumber param6)

{
//create the response payload
GetLuckyNumberResponse res = new GetLuckyNumberResponse();
//get parameter
Calendar dOfB = param6.getParam0();
//businesslogic
int luckyNumber = myService.getLuckyNumber(dOfB.getTime());
//put result in response payload
res.set_return(luckyNumber);
//return the payload
return res;
}

}
Step 5: Create ".aar" file which has to be deployed inside axis2 using the below command.
The build.xml file is created in Step 3.

ant build.xml

Step 6: Deploy.

A new folder build is created inside the current directory. The MyNewService.aar file is present in \build\lib. Upload this using the axis2 admin page. Refer previous tutorial for more details.

Step 7: Test the service.

type http://localhost:8080/axis2/services/MyNewService?wsdl in address bar. you should get the WSDL file.

Step 8: Code the Client using the generated Stub. The code is explained with appropriate comments.

package axis2.adb.async.client;
import java.rmi.RemoteException;
import java.util.Calendar;
import java.util.Date;
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import axis2.adb.async.MyNewServiceStub;
import axis2.adb.async.MyNewServiceCallbackHandler;
import axis2.adb.async.xsd.GetLuckyColor;
import axis2.adb.async.xsd.GetLuckyNumber;

public class MyNewServiceClient {
private static int luckyNumber = 100; //assume some large number
private static String luckyColor = null;
private static boolean twoWayListnerEnabled = false; //When true a asynchronous dual channel non-blocking service will be used

public static void main(String[] args) {
MyNewServiceStub stub = null;
ConfigurationContext configContext = null;
try {
if(twoWayListnerEnabled){
//Since this is the client, addressing module has to be engaged. Copy the "repository" directory, present in %AXIS2_HOME%, to a convenient place and give its path as first argument to the below method. Copy the axis2.xml from %AXIS2_HOME%/conf into convenient location, and give its path as second argument. Edit the axis2.xml to change the port to say, 8082.
configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repository", "repository/modules/axis2.xml");
stub = new MyNewServiceStub(configContext,"http://localhost:8080/axis2/services/MyNewService");
}else{
stub = new MyNewServiceStub(null,"http://localhost:8080/axis2/services/MyNewService");
}
// set the call back handler. Note that call back methods given override the ones in CallBackhandler abstract class.
MyNewServiceCallbackHandler myNewServiceCallBackHandle = new MyNewServiceCallbackHandler(){
public void receiveResultgetLuckyNumber(
axis2.adb.async.xsd.GetLuckyNumberResponse param43) {
luckyNumber = param43.get_return();
}
public void receiveResultgetLuckyColor(
axis2.adb.async.xsd.GetLuckyColorResponse param41) {
luckyColor = param41.get_return();
}
};
if(twoWayListnerEnabled){
//engage the module, and setUseSeparateListner to true.
stub._getServiceClient().engageModule(new QName("addressing"));
stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(1000);
stub._getServiceClient().getOptions().setUseSeparateListener(true);
}
//call the service
getLuckyNumberFromService(stub,myNewServiceCallBackHandle,new Date(1987,12,21));
// Since async call, poll the luckyNumber to see if a value is populated. This is just an example, in practice, should not poll this way. Here it is required cas' the number is an input to the next service all.
do{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if(luckyNumber != 100){
break;
}
}
}while(luckyNumber == 100);
//call the next service
getLuckyColorFromService(stub,myNewServiceCallBackHandle,luckyNumber);
// again poll to see if lucky color has been populated.
do{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if(luckyColor != null){
break;
}
}
}while(luckyColor == null);
//print them
System.out.println("Lucky Number: " + luckyNumber);
System.out.println("Lucky Color: " + luckyColor);

} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException re){
re.printStackTrace();
}finally{
//do the clean up.
try {
if(twoWayListnerEnabled){
stub._getServiceClient().disengageModule(new QName("addressing"));
stub._getServiceClient().cleanup();
}
stub.cleanup();
if(twoWayListnerEnabled){
System.exit(0);
}
} catch (AxisFault e) {
//ignore this
}
}

}
private static void getLuckyColorFromService(MyNewServiceStub stub, MyNewServiceCallbackHandler myNewServiceCallBackHandle, int luckyNumber) throws RemoteException {
//create request payload
GetLuckyColor req = new GetLuckyColor();
//set the parameter
req.setParam0(luckyNumber);
// do an async call
stub.startgetLuckyColor(req, myNewServiceCallBackHandle);
}
private static void getLuckyNumberFromService(MyNewServiceStub stub, MyNewServiceCallbackHandler callBackForGetLuckyNumber, Date date) throws RemoteException {
//create request payload
GetLuckyNumber req = new GetLuckyNumber();

Calendar dOb = Calendar.getInstance();
dOb.setTime(date);
//set the parameter
req.setParam0(dOb);
//do an async call
stub.startgetLuckyNumber(req, callBackForGetLuckyNumber);

}

}



Step 9: Execute the client.

java MyNewServiceClient

output :
Lucky Number: 2
Lucky Color: Yellow


Hope, this tutorial was use full enough. Here, ADB databinding was used and no security implemented. Next will try to get an Webservice up with security implementation.
Adios!!

using tcpmon with axis2 webservices and tomcat

Using tcpMon utility with web services is very easy. Download the jar file from h**p://ws.apache.org/commons/tcpmon/download.cgi. Extract it. Run the tcpmon.bat. This will launch the tcpmon UI. Give the host name (localhost) and the target port# (8080). Give the listener port# to 8081 and say add. This will create a new tab. On this tab, there are two text frames. The top one shows the request, and the bottom one shows the response.
In the client, use the target end point uri with port 8081 instead of 8080(my tomcat server listens to this). This will allow you to see the request and response messages in this small and powerful utility. There is more to this tool, which you can read from the user guide.

Sunday, March 25, 2007

Step by step Web Services with Axis2 Tutorial in Java

It was very hard for me to get a good tutorial on developing web services with axis2 on the internet. After some effort I was able to deploy a axis2 web service. I hope this tutorial below will help you for bringing up the web service using axis2 a lot easier.(This shows sync/blocking call client).
The tutorial shows how to get your web service up as quickly as possible, with out giving intrinsic details. For more details regarding any aspect of the tutorial, the axis2 documents will assist you.

My Configuration:

a) AXIS2 1.1.1

b) JDK 1.5

c) ANT 1.7.0

d) TOMCAT 5.5


Before proceeding, please read the installation doc of axis2 so that it will work with tomcat with no problems. The below steps assumes that the axis2 is configured with tomcat and is running in the tomcat container. You can test the same by visiting http://localhost:8080/axis2/ url, and then clicking on the validate link.


Step 0: Set the following paths in your system.(This step is very important)
a) AXIS2_HOME = "your axis2 installation(unzipped) directory"
b) JAVA_HOME = "your jdk installation path"
c) PATH = "add ant, axis2/bin to this"

Step 1: Create your service class.

In my case:

package axis2.adb;
public class MyService {
public String sayWelcomeToAxis2(String userName){
return "Hi " + userName + "\nWelcome to the world of Axis2";
}
}

You can actually use an interface to define the service contracts, which your service will implement. But, as i said, the goal is to set the webservice up as fast and in as simple way as possible.

Step 2: Generate the WSDL file using the command:
java2wsdl -cp ./bin -cn axis2.adb.MyService -of ./META-INF/MyService.wsdl

here -cp gives the classpath, in my case the class files are present in 'bin' folder. -cn is the class name with package and -of is the output file.

Step 3: Generate the Skeleton using the below command. I will be using the ADB(Axis data binding). You can use XMLBean or JiBx or AXIOM also.

wsdl2java -uri ./META-INF/MyService.wsdl -p axis2.adb -d adb -s -ss -sd -ssi -o .

here uri provides you with the WSDL file path, -p specifies the package, -d gives the data binding(ADB in my case), -s sync call, -ss creates the server side code (skeleton and related files), -sd creates a service descriptor (services.xml file), -ssi switch creates an interface for the service skeleton.

Step 4: Put the business logic inside the skeleton.

package axis2.adb;
import axis2.adb.MyService;
import axis2.xsd.SayWelcomeToAxis2Response;
/**
* MyServiceSkeleton java skeleton for the axisService
*/
public class MyServiceSkeleton implements MyServiceSkeletonInterface {
MyService myService = new MyService();
/**
* Auto generated method signature
*
* @param param2
*
*/
public axis2.xsd.SayWelcomeToAxis2Response sayWelcomeToAxis2(
axis2.xsd.SayWelcomeToAxis2 param2)
{
//create the response obj
SayWelcomeToAxis2Response res = new SayWelcomeToAxis2Response();
//set the response payload
res.set_return(myService.sayWelcomeToAxis2(param2.getUserName()));
// return the response
return res;
}
}

Step 5: Create the Client Stub using the command below.

wsdl2java -uri ./resources/MyService.wsdl -p axis2.adb.client -d adb -s -o .

Step 6: Code the Client using the generated Stub.

package axis2.adb.client;
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
public class MyServiceClient {
public static void main(String[] args) {
try {
//create the stub
MyServiceStub stub = new MyServiceStub("http://localhost:8080/axis2/services/MyService");
// webservice call happens inside this method
sayWelcome(stub);
} catch (AxisFault e) {
e.printStackTrace();
}
}
private static void sayWelcome(MyServiceStub stub) {
//create the request payload
MyServiceStub.SayWelcomeToAxis2 req = new MyServiceStub.SayWelcomeToAxis2();
//set the parameter
req.setUserName("SacroSanctBlood");
MyServiceStub.SayWelcomeToAxis2Response res = null;
try {
//get the response(This example shows a blocking call)
res = stub.sayWelcomeToAxis2(req);
//show the output
System.out.println(res.get_return());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}


Step 7: Create ".aar" file which has to be deployed inside axis2 using the below command.
The build.xml file is created in Step 3.

ant build.xml

Step 8: Deploy.

A new folder build is created inside the current directory. The MyService.aar file is present in \build\lib. Upload this using the axis2 admin page.
Type, http://localhost:8080/axis2/. Click on Administration. Login using the username/password, by default it is admin/axis2. (present in %AXIS2_HOME%/conf/axis2.xml) Use the Upload Service tool present in the left side of page. Upload the MyService.aar.

Step 9: Test the service.

type http://localhost:8080/axis2/services/MyService?wsdl in addressbarr. you should get the WSDL file.

Step 10: Execute the client.

java MyServiceClient


output :

Hi SacroSanctBlood

Welcome to the world of Axis2

Hope, this tutorial was use full enough.
Next time, will try to put up the async/non-blocking version of the web service.