How to deploy JSR181 annotated class in Apache Axis2

JAX-WS (Java API for XML Web Services) provides support for annotating Java classes with metadata to indicate that the Java class is a Web service. With the annotations, you can expose java classes as web services with minimum effort.
Apache Axis2 ships with JAX-WS support since its 1.4 release. This post explains the simplest possible scenario of JAX-WS support, how you can deploy an annotated class in Axis2.

Pre-requisites
Apache Axis2-1.4 or later
JDK1.5 or above

Step 1
Write an annotated class as follows.

package org.apache.axis2;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class Calculator {
@WebMethod
public double Add(double x, double y){
return x+y;
}
}

Here, the @WebService annotation tells the server runtime to expose all public methods on the above class as a Web service. Also, with the @WebMethod annotation, you can specifically denotes the methods which are exposed in the web service.

Step 2
Package the above class as a JAR (i.e:- Calculator.jar).
You need to create a directory in Axis2 binary distribution where the annotated jars are placed.
Therefore go to AXIS2_HOME/repository (AXIS2_HOME is where you extracted the binary distro) and create a new directory called, servicejars.

cd AXIS2_HOME/repository
mkdir servicejars

Step 3
Copy the annotated jar file to the servicejars directory. Then, start Axis2server (AXIS2_HOME/bin/axis2server.bat{sh})

Step 4
Go to http://localhost:8080
You will see that the calculator class will be exposed as a web service. Click on the service name.
You will be directed to the following URL and the WSDL of the service can be viewed there.
http://localhost:8080/axis2/services/CalculatorService.CalculatorPort?wsdl

Step 5
Service Deployement is over by now. Lets invoke this service using a client. I will use SOAPUI for the demonstration, you may choose any of the available mechanisms.

Open SOAPUI and start to create a new WSDL project.
Enter the above WSDL path(http://localhost:8080/axis2/services/CalculatorService.CalculatorPort?wsdl) as the initial WSDL.
Select the request, provide inputs and submit. You will get the expected results back.



You can find more information about Axis2 JAX-WS API from here.

Comments

Unknown said…
I deployed sample web services as jar using annotations (avoiding services.xml), but it's generating only ...wsdl2 and not able to generate the original ...wsdl.
So if I try to point to wsdl (wsdl1) then it throws:

Unable to generate WSDL 1.1 for this service---
reason--If you wish Axis2 to automatically generate the WSDL 1.1, then please +set useOriginalwsdl as false in your services.xml

It is applicable for both POJO and Jar deployments. But the same works abolutely fine if I bundle as a .aar file including the services.xml
Charitha said…
Hi Upananda,
Could you please try with a latest Axis2 SNAPSHOT build instead of Axis2-1.4 or 1.4.1 release? I think this has been fixed now.

Regards
Charitha
Arun said…
Hi Charitha,
I too get the same error with axis2-1.4.1. Where can I find the SNAPSHOT build. Can you provide a link.
Charitha said…
Arun,
Can you please download jaxws-rt.jar and jaxws-tools.jar and copy them to AXIS2_HOME/lib directory. Then restart axis2server and try again.

Regards
Charitha

PS:- You can download these jars from http://www.java2s.com/Code/Jar/wsit/jaxws-rt.jar.htm
Arun said…
Thanks Charitha.
I downloaded the jars from the place you mentioned but i face the same issue.
From my catalina.out I get the following error

==================
[ERROR] Error occurred generating WSDL file for Web service implementation class {Calculator}: {java.lang.reflect.InvocationTargetException}
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

.............
...........
Caused by: java.lang.NoClassDefFoundError: com/sun/mirror/apt/AnnotationProcessorFactory
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1847)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:890)
.........
............

====================

One more thing wanted to add to this is that I am working on JDK1.5. One of link (http://www.nabble.com/-jira--Created:-(AXIS2-3693)-JAXWSRIWSDLGenerator-needs-tool.jar-on-classpath-td16442812.html) indicated that for JDK1.5 i would need to put the follwing jars
jaxws-rt-2.1.*.jar ,
jaxws-tools-2.1.*.jar,
stax-ex-1.0.jar ,
streambuffer-0.7.jar,
and of course tools.jar.

I did the above but didnot help me and I get the same error I indicated above. Can you help me what I am missing here. Does this not work on jdk1.5 (since thats what I use)? Other than this, I am working on axis2-1.4.1 and tomcat 6.0. Any other you would need, I am glad to put across.
Charitha said…
Hi Arun,
Could you please do one more simple test with Axis2-1.4.1?

1. Download the simpleJaxwsService.jar from http://ww2.wso2.org/~charitha/jaxws/
2. Copy to AXIS2_HOME/repository/servicejars directory
3. Make sure jaxws-rt.jar and jaxws-tools.jar reside in AXIS2_HOME/lib
4. Open a browser and issue
http://localhost:8080/axis2
5. Select the simpleJaxwsservice in the service list
6. You will get the wsdl of the service

This should work for you. I just tested this with Axis2-1.4.1/jdk15

Let me know how it goes.

Regards
Charitha
Arun said…
Hi Charitha,
I appreciate your quick response and getting back on this.

I did what you said but again I get the same problem.

catalina output is the same:
======
[ERROR] Error occurred generating WSDL file for Web service implementation class {org.test.SimplejaxwsService}: {java.lang.reflect.InvocationTargetException}
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
..........
........
[ERROR] Error occurred generating WSDL file for Web service implementation class {org.test.SimplejaxwsService}: {java.lang.reflect.InvocationTargetException}
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

=====
I wonder how my enviroment is different from yours.
Here are some of the outputs from mine.

======
[root@SERVERWGP lib]# ll jaxws-*
-rw-r--r-- 1 root root 1150174 Sep 21 2007 jaxws-rt.jar
-rw-r--r-- 1 root root 500336 Sep 21 2007 jaxws-tools.jar

[root@SERVERWGP servicejars]# pwd
/opt/apache/apache-tomcat-6.0.18/webapps/axis2/WEB-INF/servicejars
[root@SERVERWGP servicejars]# ll
total 8
-rw-r--r-- 1 root root 868 Feb 16 11:55 Calculator.jar
-rw-r--r-- 1 root root 1007 Feb 16 17:04 SimplejaxwsService.jar

=====================

The URL I try to get the wsdl,
http://localhost:8080/axis2/services/SimplejaxwsServiceService.SimplejaxwsServicePort?wsdl

[root@SERVERWGP logs]# echo $JRE_HOME
/usr/java/jdk1.5.0_12/

==============

Another thing I wanted to add to this is that I am running on this on a linux platform.
====
[root@SERVERWGP logs]# uname -a
Linux SERVERWGP 2.4.21-15.EL #1 Thu Apr 22 00:27:41 EDT 2004 i686 i686 i386 GNU/Linux
=====
Charitha said…
Could you please try with axis2server instead of tomcat? It seems you are running on axis2 on tomcat. That should not be a problem. However, I tried with standalone axis2. In order to isolate the issue, could you please give a try with axis2server?

Regards
Charitha
Arun said…
Hello Charitha,
Yes. When I use Axis2Server the program works well and the wsdl is generated.
So looks like there is an issue when we have axis deployed on top of tomcat (using axis2.war).
Wondering what could be the difference and why deployment of using the "servicejars" doesnot work. Interestingly the deployment of .aar works on tomcat + axis2. Is it some kind of dependency lib that has been missed out.
There definetly seems some difference between .aar deployment (in services) and a .jar in servicejars and the way in which wsdl gets generated.

Thanks for looking and supporting this issue. I appreciate this.

Regards
Arun
Charitha said…
Arun,
I just tried with axis2.war deployed on tomcat 6.0.10 and I did not get such error. It worked fine. How did you get axis2.war? Did you download it from axis2 web site?
I created the war manually from the binary distribution as follows.
- go to AXIS2_HOME/webapp directory
- Type 'ant create.war'
- This generates axis2.war in AXIS2_HOME/dist directory
- Then I deployed it on tomcat

There are no differences between the war created using binary and the one hosted in axis2 web site. But, to see why you get this error and I'm not, please check the above procedure as well.
Arun said…
Hi Charitha,
I downloaded the war file from the apache site.
http://ws.apache.org/axis2/download/1_4_1/download.cgi

I didn't carry out any build like you did. Since war file was available as a distribution, I just used them and deployed on top of tomcat.

Below is the size of Axis2 that I downloaded from the above link.

[root@SERVERWGP webapps]# ll axis2.war
-rw-r--r-- 1 root root 19240072 Jan 21 12:25 axis2.war
[root@SERVERWGP webapps]#

Is this the same that got generated after the build (I mean the size).

Arun
Arun said…
I have build axis2 (1.4.1) using ant 1.7 and got the axis2.war. Deployed in tomcat 6.0.18. I do see that the servicejars dir gets automatically created now and the sample jar file SimplejaxwsService.jar is present as part of the distribution. Moreover the libraries jaxws-rt.jar and
But, I face the same problem when I access the URL. The catalina logs says the error which I printed earlier.

Only thing I see a difference between your setup and mine is that I use a higher version of tomcat (which theortically shouldn;t make a difference).
Arun said…
Hi Charitha,
Is it possible for you to place the war that you used in a public place so that I can deploy it on top of tomcat and validate if it works.

This way I will isolate if I did any mistake.

Thanks
Arun
Charitha said…
Hi Arun,
Sorry I could not respond due to some project works. I have placed axis2.war in the following location [1].

Please get it and check with it.

[1]http://ww2.wso2.org/~charitha/jaxws/
Arun said…
Thanks Charitha.
I appreciate the response.
With war that you have provided, I get the same problem. I end up with the same error messages that I pasted before for deployments under service jars.
I have a doubt if the classpath is getting set properly to see the jaxws-rt.jar and jaxws-tools.jar in tomcat deployments. Clearly it looks like when i click on the link of wsdl. Did you add any classpath manually in the startup scripts of tomcat.
Arun said…
After adding tools.jar in the tomcat path, I am able to see the wsdl URL properly in tomcat 6.0.18. I think is required. Thanks for all help in supporting and resolving the issue.
Arun said…
Hi Charitha,
I did the complete service jars deployment and works well when the responses are primitives. When I use objects as return responses I get an error.

-----
[ERROR] javax.xml.bind.JAXBException: class endpoint.data nor any of its super class is known to this context.
org.apache.axis2.AxisFault: javax.xml.bind.JAXBException: class endpoint.data nor any of its super class is known to this context.
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:220)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:17
==========
Can you let me know if I missed anything more here.

Here is my code
========================

@WebService(name = "Calculator",targetNamespace="http://endpoint/")
//@XmlSeeAlso({endpoint.data.class})
public class Calculator {


/**
*
* @param value1
* @param value2
* @return
* returns int
*/
@WebMethod(action = "add")
@WebResult(name="result",targetNamespace="http://endpoint/")
@RequestWrapper(localName = "addRequest",targetNamespace="http://endpoint/",className="endpoint.addRequest")
@ResponseWrapper(localName = "dataResponse",targetNamespace="http://endpoint/",className="endpoint.data")
public data add(
@WebParam(name = "value1",targetNamespace="http://endpoint/")
int value1,
@WebParam(name = "value2",targetNamespace="http://endpoint/")
int value2){
data d = new data();
d.setAttr1("test1");
d.setAttr2("test2");
d.setAttr3("test3");
return d;
}

}
====================
Any my data.java would be,

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "data", propOrder = {"attr1", "attr2","attr3"})
//public class data implements java.io.Serializable {
@XmlRootElement(name="dataResponse")
public class data {
//@XmlElement(name = "attr1")
@XmlElement(nillable = true)
private String attr1="testatr1";
//@XmlElement(name = "attr2")
private String attr2="testatr2";
// @XmlElement(name = "attr3")
private String attr3="testattr3";

public String getAttr1(){ return attr1; }
public void setAttr1(String atr){
attr1 = atr;

}

public String getAttr2(){ return attr2;}
public void setAttr2(String atr){
attr2 = atr;

}
public String getAttr3(){ return attr3;}
public void setAttr3(String atr){
attr3 = atr;
}
}
=====================

Can you help me why I get that exception from server.
Anonymous said…
Thank you so much!!polo shirt men'ssweate,Burberry Polo Shirts lacoste sweater, ralph lauren Columbia Jackets,ski clothing. Free Shipping, PayPal Payment. Enjoy your shopping experience on mensclothingus.com.You can find the father who desire fashionable, intellectual mens clothing simultaneously.

http://www.pumafr.com/blog
http://poloshirtsonline.blogspot.com
http://thediary.org/mensclothing
http://blog.livedoor.jp/dokoma
http://www.itimes.com/my_blog.php
Anonymous said…
Do not mean bad.Thank you so much!I just want to show some fashion things to all of you.I like puma speed, puma femmes and other puma shoes. These puma sport items are at store recently and available for anyone.
Puma sport
polo shirts
polo shirts
gillette razor blades
original polo clothing
Sara Reid said…
The things were simple, i included multiple jar files needed for axis enviornment. I included them in my classpath and also put them in my Tomcat lib folder. So i remove the axis jars from tomcat/lib but it gives me more exception. Then, I removed them from classpath and put them in Apache Tomcat /lib folder.

carte sdhc 16gb
Hiro Gangwani said…
Hi,
I have built the web service using jaxws annotations and followed the same steps as mentioned in the blog.when i am deploying the application with eclipse IDE, web service is getting published properly and in can invoke the same using SOAP UI client. But when i export the project and deploy as war file in web logic application server, application is unable to deploy and publish the web service. Can u pls help me in resolving this issue?

Thanks in advance,
hiro

Popular posts from this blog

WSO2 Stratos - Introducing WSO2 middleware Platform as a Service (PaaS)

Common mistakes to avoid in WSO2 ESB - 1 - "org.apache.axis2.AxisFault: The system cannot infer the transport information from the URL"

Working with HTTP multipart requests in soapUI