This is a continuation of the previous entry, where we dealt pimarily with building a pom project for the JAX-WS RI 2.1 EA3 jars so that we can reference in our Web Services maven java project. Personally, I am not really sure about all this WS-* specification now being pimped as a way to deliver on the (drum-roll,please) SOA principle. But, that is what my current activities are focused on, so I need to keep plugging away.
So if you remember from the previous entry we will be working on the contract-last paradigm, where we build the service interface in JAX-WS annotated POJOS, then run it through the apt processor to generate the concrete implementations for the bindings and then deploy it in Tomcat. We will do all this in a Maven 2 project. The requirements for this project are:
- Java 5 (because of annotations)
- Maven 2
- JAX-WS RI (we will be using 2.1-EA3)
- Tomcat 5.5.16 (that is what I have tested in)
Step By Step Approach
1.1 Setting up the Maven project for JAX-WS
First thing we do is create a Maven webapp project (war artifact) and then add the dependency for JAX-WS in the pom.xml as illustrated in the previous Part 1 blog entry. The following should go in the <dependencies> element in the project (pom) file:
<dependency>
<groupId>local.sun.java.net</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.1-EA3-SNAPSHOT</version>
<type>pom</type>
</dependency>
Now, all the JAX-WS RI jars should be accessible.
1.2 JAX-WS Test Package
At this point we are ready to build the service interface, we will use the addNumbers Interface that comes with the samples bundle in the JAX-WS RI bundle and will use the JSR181 annotations. Remember, this project is just to illustrate how to build a JAX-WS RI project and deploy in tomcat. Here is my AddNumbersImpl.java file in test.testsvc package, please note for this project my service endpoint interface and the implementation class are the same. In general, you should break it up into an interface and implementation class.
package test.websvc;
import javax.jws.WebService;
@WebService
public class AddNumbersImpl{public int addNumbers(int x, int y) {
return x+y;
}
}
All the JSR181 annotation documentation can be found here. The above exports all the public methods as WS operations on our interface, in this case just the addNumbers.
1.3 Setting up the Maven Plugin to generate JAX-WS artifacts
Before you can deploy this in Tomcat, you need to generate the JAX-WS portable artifacts neccessary so that the WSServlet that we will be using (part of JAX-WS bundle) can work. Till we can find a Maven plugin to generate the artifacts we will use the good old antrun plugin to generate the artifacts and automatically inject it into the maven build mechanism. Put the following in your <build> -> <plugins> element:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>apt-task</id>
<phase>generate-sources</phase> (1)
<configuration>
<tasks verbose=”true”><property name=”gen.src.java” value=”target/generated-sources/main/java” /> (2)
<mkdir dir=”${gen.src.java}”/>
<taskdef name=”apt” classname=”com.sun.tools.ws.ant.Apt”>
<classpath refid=”maven.compile.classpath”/>
</taskdef>
<apt
fork=”true”
debug=”false”
verbose=”false”
destdir=”target/classes”
sourcedestdir=”${gen.src.java}”
nocompile=”true”
sourcepath=”src/main/java”>
<classpath>
<path refid=”maven.compile.classpath”/>
<!– this is for the apt task –>
<pathelement location=”${java.home}/../lib/tools.jar”/>
</classpath>
<option key=”r” value=”target”/>
<source dir=”src/main/java”>
<include name=”**/websvcs/**/*.java”/> (3)
</source>
</apt>
</tasks>
<!– add it to maven source root –>
<sourceRoot>${gen.src.java}</sourceRoot> (4)
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
</plugin>
Things of note (or change for your porject) are:
(1) Bind the goal to the maven generate-sources phase.
(2) Specify where the generated sources should go relative to the project ${basedir}.
(3) Include all your JSR181 annotated sources.
(4) This ensures that generated sources are added to your compile phase.
Note, here I have decided to fork the apt task so, the classpath element needs to be specified so all the jars
are found.
1.4 Deploy in Tomcat
At this point we are ready to deploy in Tomcat. Since we are going to be using the Servlet from the JAX-WS bundle, we need to ensure that the WAR adheres to the format as documented here. Note, this is a proprietary format. Basically the steps involved are:
- Create the web.xml.
- Create the sun-jaxws.xml.
- Create the archive and deploy in Tomcat.
Here is my web.xml:
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app version=”2.4″
xmlns=”http://java.sun.com/xml/ns/j2ee”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”>
<display-name>JAX-WS RI Test Web Application</display-name>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<description>Add Numbers Service</description>
<display-name>testwebsvc</display-name>
<servlet-name>testwebsvc</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testwebsvc</servlet-name>
<url-pattern>/addnumbers</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
Nothing special here except the <url-pattern> and <servlet-name> element which you will need in the sun-jaxws.xml file, which for us looks like:
<?xml version=”1.0″ encoding=”UTF-8″?>
<endpoints xmlns=’http://java.sun.com/xml/ns/jax-ws/ri/runtime’ version=’2.0′>
<endpoint
name=”testwebsvc”
implementation=”test.websvc.AddNumbersImpl”
url-pattern=”/addnumbers”/>
</endpoints>
Note the implementation is set to our @WebService annotated class (if you used the Interface/Implementation class pattern, this would be the implementation class).
1.5 Conclusion
Hoepfully this is useful information for people on the bleeding edge, using maven 2 and want to try out the JAX-WS RI implementation from java.net and deploy it in Tomcat. I do need to mention that I tried XFire 1.2.3 too and really like it as you can skip the step of generating the artifacts as it is done at runtime, but I did run into known issues with Spring 2.0,JAXB2 and JAX-WS 2, so I will have to wait till it is fixed.
