Web Services Example Using Axis 2 and Tomcat

Aim
The aim of this Java Axis tutorial is to write a simple 'Hello World' web service and client in Java, using the Axis2 framework. Once created, the web-service will be deployed in Axis2, running on Tomcat. The client will be a remote Java client. Leave any questions or problems as comments and I will endeavour to answer them. See Web Services Using JWSDP and Tomcat for a Sun alternative.

Assumptions
This article assumes that you have Axis 2 installed and configured on Tomcat and you have a working version of the Java JDK. Please see Setting up Axis2 on Tomcat for more details. For purposes of this example Tomcat is running on port 8080 and the project directory is Axis2TomcatHelloWorld. Also for tcpmon you have the axis.jar file from Axis1 installed. Again see Setting up Axis2 on Tomcat for more details.

Versions used in this example
Sofware/ComponentImage
Windows XP SP2N/A
Axis 2 (bin)Axis2-1.4-bin.zip
tomcat 6apache-tomcat-6.0.18.zip
Java JDK 1.5.0N/A
Axis 1 (for tcpmon)axis-bin-1_4.tar.gz
jav Links to these files can be found here.

Although this is a quick 'helloworld' tutorial we will not sacrifice neatness for speed - so all the source files, class files etc will be kept in separate directories and as clean as possible. You will thank me for this later.

Create this directory structure in your working directory- similar to something you would get from eclipse. The structure used in this example is given below. Axis2TomcatHelloworld will be referred to as your project or working directory. Create this structure.

Axis2TomcatHelloworld
_|_client_bin
_|_client_src
_|__|_Axis2TomcatHelloWorldClient.java
_|_web_bin
_|__|_META-INF
_|__.__|_services.xml
_|_web_src
_.__|_HelloWorldServiceImplementation.java
_.__|_HelloWorldServiceInterfacejava

You can download the zipped example here.


The axis 2 binaries are unzipped in D:\downloads\axis2\axis2-1.4.1 directory for this tutorial.


Compiling the webservice code
  1. Write the code. We don't really need an interface for this example, but I have added one for completeness, because we will use these exact same files for the JWSDP example. The  HelloCallEcho function will be exposed in this tutorial.
     1. package helloworld;
     2. 
     3. import java.rmi.RemoteException;
     4. 
     5. public interface HelloWorldServiceInterface extends java.rmi.Remote{
     6.     public String HelloCallEcho(String hellostring)throws java.rmi.RemoteException;
     7.     public int HelloCallAdd(int helloNumber1, int helloNumber2)throws java.rmi.RemoteException;
     8. }
    Hide line numbers
    Save this as HellowWorldServiceInterface.java in your web_src directory.
    next create the implementation.
     1. package helloworld;
     2. 
     3. public class HelloWorldServiceImplementation implements HelloWorldServiceInterface{
     4. 
     5.     public String HelloCallEcho(String hellostring) {
     6.         return "Web service echoing back - "+hellostring;
     7.     }
     8.     
     9.     public int HelloCallAdd(int helloNumber1, int helloNumber2) {
    10.         return helloNumber1 + helloNumber2;
    11.     }
    12. }
    Hide line numbers
    Save this as HelloWorldServiceImplementation.java under in your web_src directory.
  2. Open a command prompt and cd into your project directory (Axis2TomcateHelloWorld in this example).
  3. Compile the code using,

    ..workspace\Axis2TomcatHelloWorld>javac -d web_bin web_src\*.java

  4. Your web_bin directory should have some class file in there.
  5. Create the services.xml file in the web_bin\META-INF directory.
     1. <service>
     2.    <description>
     3.       This is my first service, which says hello
     4.    </description>
     5.    <parameter name="ServiceClass">helloworld.HelloWorldServiceImplementation</parameter>
     6.    <operation name="HelloCallEcho">
     7.       <messageReceiver
     8.       class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
     9.    </operation>
    10.    <operation name="HelloCallAdd">
    11.       <messageReceiver
    12.       class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    13.    </operation>
    14. </service>
    Hide line numbers

  6. Cd into web_bin directory and jar it all up using,

    ..workspace\Axis2TomcatHelloWorld\web_bin>jar -cvf HelloWorldServices.aar *


Deploying the Service
  1. go to http://127.0.0.1:8080/axis2 - select Administration. The default username is 'admin' and the password is 'axis2.'
  2. Select upload service and navigate to the HelloWorldServices.aar and upload.
  3. Now navigate to 'available services' on the navigation pane on the left.
  4. You should be able to see your service. Click on it and it should open up yout WSDL file.

Generating the stub code - required for the client.
  1. Open a promt and cd to your working directory.
  2. Generate the client stub by running wsdl2java.bat. Wsdl2java should be in your Axis2 directory under bin. The -S specifies the output directory.
    ..workspace\Axis2TomcatHelloWorld>D:\downloads\axis2-1.4.1-bin\axis2-1.4.1\bin\wsdl2java.bat -uri http://127.0.0.1:8080/axis2/services/axis2tomcathelloworld?wsdl -S client_src
    You can now go to the client_src/helloworld directory to see the generated files.

Compiling the client
  1. Write the actual client code. All we are doing is setting up the stub and the request and then calling the function which returns a response. Save this file in the client_src directory.
     1. import helloworld.*;
     2. import org.apache.log4j.*;
     3. 
     4. public class Axis2TomcatHelloWorldClient {
     5.     static Logger logger = Logger.getLogger("Axis2TomcatHelloWorldClient.class");
     6. 
     7.     public static void main(String[] args) throws Exception {
     8. 
     9.         Axis2TomcathelloworldStub stub = new Axis2TomcathelloworldStub();
    10.         Axis2TomcathelloworldStub.HelloCallEcho helloReqEcho = 
    11.                                             new Axis2TomcathelloworldStub.HelloCallEcho();
    12.         helloReqEcho.setHellostring("client says hello Axis2");
    13.         Axis2TomcathelloworldStub.HelloCallEchoResponse helloRespEcho = 
    14.                                             stub.HelloCallEcho(helloReqEcho);
    15.         System.out.println(helloRespEcho.get_return());
    16.     }
    17. }
    Hide line numbers
    You can ignore the log4j stuff, it's just here for completetion.
  2. Now go to the client_src directory and compile it.

    ..workspace\Axis2TomcatHelloWorld\client_src>javac -d ..\client_bin -extdirs D:\downloads\axis2-1.4.1-bin\axis2-1.4.1\lib Axis2TomcatHelloWorldClient.java


Running the application
  1. CD into client_bin and run the client using the command below. Replace D:\downloads\axis2-1.4.1-bin\axis2-1.4.1\lib with the path to your Axis 2 lib directory,
    ...workspace\Axis2TomcatHelloWorld\client_bin>java -Djava.ext.dirs=D:\downloads\axis2-1.4.1-bin\axis2-1.4.1\lib Axis2TomcatHelloWorldClient
    You should see a printout saying 'hello back' from the web service.

Looking at the soap messages using tcpmon The way the monitor works is like a proxy. Your client connects to the monitor and the monitor connects to the web-service. Remember that tomcat is already running on 8080
  1. Go back and edit the Axis2TomcatHelloworldClient.java. Add the URL as the parameter to the constructor,
    originalAxis2TomcathelloworldStub stub = new Axis2TomcathelloworldStub();
    modifiedAxis2TomcathelloworldStub stub =
    new Axis2TomcathelloworldStub("http://127.0.0.1:8081/axis2/services/axis2tomcathelloworld.axis2tomcathelloworldHttpSoap12Endpoint/");

  2. Compile the code as explained previously.
  3. Open up another seprate command prompt and start up tcpmon,

    ...\anywhere>java -cp D:\downloads\axis-bin-1_4\axis-1_4\lib\axis.jar org.apache.axis.utils.tcpmon
    Please refer to the final section in the Setting up Axis2 on Tomcat for more details on this step and why we are using the axis.jar core from Axis 1. This should startup tcpmon.
  4. In the tcpmon gui, in the listen port type in 8081 and press add.
  5. Go to the 8081 tab at the top.
  6. Now open up a command prompt and run the recompiled client as explained in the previous section- You should see SOAP messages send back and forth.

31 comments:

Anonymous said...

whats the correct way to compile the client? I dont see command line instructions on how to do this. I get tons of package not found errors

gratzi

Crazy Bitch said...

Sorry my bad. I've added the command to do the compile. Looks like I'd forgotten to add it in the JWSDP2/Axis and Galssfish/Axis tutorials too. I've added them all now. Thanks for bringing it up

Anonymous said...

thanks very much for everything

killer information

Anonymous said...

i think there is a small error

http://127.0.0.1:8080/axis2/services/axis2tomcathelloworld?wsdl

should be

http://127.0.0.1:8080/axis2/services/HelloWorldServices?wsdl

Anonymous said...

another minor error

D:\downloads\axis2-1.4.1-bin\axis2-1.4.1\bin\wsdl2java.bat -uri

should be

D:\downloads\axis2-1.4.1\bin\wsdl2java.bat -uri

Anonymous said...

Error Generating the client stub by
------------------------------- running wsdl2java.bat
---------------------
The AXIS2_HOME environment variable is not defined correctly
This environment variable is needed to run this program

skanth said...

hi... this is very very good.
Thanks a lot.
But i think there s a small mistake in compile command of client class
javac -d ..\client_bin -Djava.ext.dirs=D:\downloads\axis2-1.4.1-bin\axis2-.4.1\lib Axis2TomcatHelloWorldClient.java

it should be
javac -d ..\client_bin -extdirs=D:\downloads\axis2-1.4.1-bin\axis2-.4.1\lib Axis2TomcatHelloWorldClient.java

righteous said...

Thanks skanth.

I fixed it for consistency. Note that you can compile using the -Djava.ext.dirs option without a problem, but it should be used only for the runtime.

Thanks again.

Anonymous said...

Everything went smooth till the Stub generation.

After that I am finding it difficult to compile and run

Can you guide me ?

righteous said...

Love to help, email me at righteous.ninja@gmail.com or post your problem in another comment.

santiago_762000 said...

I have a question how can I hide the names of the Available Operations in the Available Services (http://localhost:8080/xyz/services/listServices)? This is because anyone who navigate by the url would access to the functions.

Thanks for all Santiago

righteous said...

Hi Santiago, you should never expose this interface to the internet. Ideally your ws server should be behind reverse proxies that will restrict access and offer better security.

winllen said...

Hi,

I am new to web services and I'm having a problem on my first project. Can anyone help me on how to create a web service having login(username, password) method which will return a session id if the user and password authentication is successful?

Thanks. any response will be very much appreciated.

bessi-

righteous said...

The standard way is to create a web service that accepts a username and password, authenticates against a db or ldap and returns a session-id. Then for every request require the session-id to be passed in the SOAP header.

Zardosht Hodaie said...

Hi,
thank you for this clear and good tutorial.
I'm using axis2-1.5.1 and the code for client does not compile.
I think the client code must be written again to comply to axis2-1.5.1 generated stub. For example in generated stub there is no setHellostring("") method in HelloCallEcho class, and the stub class itself is not named Axis2TomcathelloworldStub but merely HelloWorldServiceStub.
Am I guessing right? or something else went wrong?

Anonymous said...

Hi,

I was guided very well from this tutorial, thank you for that.I have one more question.I also face the same problem that Zardosht Hodaie has faced.Could you suggest any solution for that?

Anonymous said...

Hey Can you please fix the client code. I am kinda struck there.

Thanks in advance

Anonymous said...

Wow, awesome tutorial. I was struggling for days trying to create a java web service and this finally helped me do it !

Super excellent job ! :-)
I even clicked a bunch of your ads as a sign of appreciation !!!

Mike M in Santa Monica, CA said...

Great tutorial, I looked around everywhere trying to find information like this and was lucky enough to find your tutorial. Can't thank you enough for posting this. Excellent work!

Mike

lucky said...

hi i get following message saing service.xml not available.please help me out.
Error: org.apache.axis2.deployment.DeploymentException: The services.xml file cannot be found for the service: C:\apache-tomcat-5.5.33\webapps\axis2\WEB-INF\services\HelloWorldServices.aar at org.apache.axis2.deployment.repository.util.ArchiveReader.processServiceGroup(ArchiveReader.java:151) at org.apache.axis2.deployment.ServiceDeployer.deploy(ServiceDeployer.java:81) at org.apache.axis2.deployment.repository.util.DeploymentFileData.deploy(DeploymentFileData.java:136) at org.apache.axis2.deployment.DeploymentEngine.doDeploy(DeploymentEngine.java:597) at org.apache.axis2.deployment.repository.util.WSInfoList.update(WSInfoList.java:144) at org.apache.axis2.deployment.RepositoryListener.update(RepositoryListener.java:330) at org.apache.axis2.deployment.RepositoryListener.checkServices(RepositoryListener.java:227) at org.apache.axis2.deployment.DeploymentEngine.loadServices(DeploymentEngine.java:131) at org.apache.axis2.deployment.WarBasedAxisConfigurator.loadServices(WarBasedAxisConfigurator.java:284) at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:82) at org.apache.axis2.transport.http.AxisServlet.initConfigContext(AxisServlet.java:516) at org.apache.axis2.transport.http.AxisServlet.init(AxisServlet.java:436) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:966) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3996) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4266) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:760) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:884) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:737) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:498) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1203) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:319) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022) at org.apache.catalina.core.StandardHost.start(StandardHost.java:736) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) at org.apache.catalina.core.StandardService.start(StandardService.java:448) at org.apache.catalina.core.StandardServer.start(StandardServer.java:700) at org.apache.catalina.startup.Catalina.start(Catalina.java:552) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433) Caused by: org.apache.axis2.deployment.DeploymentException: The services.xml file cannot be found for the service: C:\apache-tomcat-5.5.33\webapps\axis2\WEB-INF\services\HelloWorldServices.aar at org.apache.axis2.deployment.repository.util.ArchiveReader.processServiceGroup(ArchiveReader.java:148) ... 37 more

Durga said...

Hi Please help.

When i try to compile the client it is giving the following warning..
Note: .\helloworld\Axis2TomcathelloworldStub.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
and when i try to run the client program..i am getting connection timedout error.

Durga said...

I tried with both JDK 1.5.10 and JDK6

Durga said...

Hi ,

This is working through SOAPUI, but not working throuhg command prompt.

Please help me out here.
thanks,

righteous said...

Hi Durga,

You have to be a bit more descriptive with the error you are getting.

Anonymous said...

Excellent tutorial! It really helped me getting an axis2-hello world test case to work. Next struggle will be to use axis2/c for the service and axis2/java for the client.

However, I wonder about one thing: How was the web_src/axis2tomcathelloworld.wsdl generated? Was it written by hand? Made by some tool from the service-source files? Since this is essential to make, in order to make use of wsdl2java for generation of the client source, I really need to know more about this...

Jay

Anonymous said...

To those with axis2-1.5.1: If you use e.g. Eclipse, it will help you with the conversion, you will for instance easily see that there is a member setArgs0 which seems to have the same signature as setHellostring and so on...

Jay

Dan B said...

Hi,

I was doing fine until I got to the section where you compile the client. I am using axis2-1.4.1. Here is the command line and error:

C:\axis2-1.4.1\samples\Axis2TomcatHelloworld\client_src>javac -d ..\client_bin -extdirs C:\axis2-1.4.1\lib Axis2TomcatHelloWorldClient.java
Axis2TomcatHelloWorldClient.java:11: cannot find symbol
symbol : method setHellostring(java.lang.String)
location: class helloworld.Axis2TomcathelloworldStub.HelloCallEcho
helloReqEcho.setHellostring("client says hello Axis2");
^
Note: .\helloworld\Axis2TomcathelloworldStub.java uses unchecked or unsafe opera
tions.
Note: Recompile with -Xlint:unchecked for details.
1 error

So it seems there is a problem with the method setHellostring, i.e. it's not in the Axis2TomcathelloworldStub? There have been other posters with the same issue ... any ideas on how to fix this?

Thanks

Dash said...

Hi i just tried using the program today.
try using
helloReqEcho.setParam0("client says hello Axis2"); which solves the issue.

Thanks.

Anonymous said...

Hi,

Very useful document. I am stuck at client compilation though,

My stub class name is not
Axis2TomcathelloworldStub.java, also there is no class file exist for it. My stub class name is HelloWorldServicesStub.java which I tried to replace in client file but still not compiling..pleas help!!!

Thanks
Shilpa

Anonymous said...

It looks like every version of axis2 is compiling the stub classes a little differently so you have to look at your HelloWorldServicesStub.java and see what axis named the methods.

Changing the helloReqEcho.setHellostring to helloReqEcho.setArgs0 worked for me.

I also had to change stub.HelloCallEcho to stub.helloCallEcho

That fixed the compile errors and then I ran it successfully.

Good luck to all and thx for the tutorial.

-Redeemed

Anonymous said...

Hi ,

Thanks a ton for a very handy tutorial. Very good approach for a newbie like me.


Regards,
Prasenjit