Monday, November 9, 2009

Contract-First Web Services in practice - part 5 of 5 (Java / J2EE)

This is the last article in the series of 5 and today we're looking at contract first development in Java/J2EE. I've left this for last after considering PHP and NET due to the various application servers and technologies in which this is possible. Java is also my forte hence I'm not shying away from this challenge. We'll look at JAX-WS on J2EE and Tomcat.

JAX-WS / EE5 Application Servers
If you prefer the blue pill and like the neat, java 5+, annotation heavy, jaxws-does-everything-for-you alternate reality, then you're in for a treat. The JAX-WS RI is available in most J2EE servers. I've picked JBOSS (the 4.2.2 GA) which is what I was using for work. JBOSS ships with wstools in the bin directory. Run the command "wsconsume -k SampleService.wsdl". This creates client stubs and a server interface "com.kimenye.SampleServicePortType". This is the class to be implemented. Once this is done, create a web.xml file and create a servlet with the servlet-class as the implementation created. Package this as a web-archive, and pop it into the deploy directory of the app server.

Tomcat 6
Tomcat 6 is a servlet container and not a full J2EE container hence it is not compulsory for it to provide JAX-WS. See my post on how to configure Tomcat 6 to use JAX-WS. Follow the steps below to implement the sample service:
  1. Use "wsimport" tool to create the service stubs. This tool is available from the bin directory of an unpacked JAX-WS installation. The full command to run is : wsimport -keep SampleService.wsdl
  2. Create a web application in your preffered IDE. Copy the artifacts generated from the wsimport into your source. Implement the port type interface. For our example this class will be com.kimenye.ProvisionServicePortType. Compile the implementations and the generated classes.
  3. Copy the wsdl into a folder named wsdl under the WEB-INF directory.
  4. Create a file named sun-jaxws.xml in the WEB-INF directory and fill in the content below:
    1. <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
    2. version="2.0">

    3. <endpoint name="SampleService" interface="com.applicationsnet.service.soap.SampleServicePortType"
    4. implementation=com.kimenye.SampleServiceImpl" wsdl="WEB-INF/wsdl/SampleService.wsdl"
    5. service="{http://kimenye.com/}SampleService" port="{http://kimenye.com/}SampleServicePort"
    6. url-pattern="/SampleService" />

    7. </endpoints>
  5. Edit the web.xml file to include the content below:
    1. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    3. version="2.4">
    4. <description>sample</description>
    5. <display-name>sample</display-name>
    6. <listener>
    7. <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    8. </listener>
    9. <servlet>
    10. <description>Sample End-Point</description>
    11. <display-name>Sample End-Point</display-name>
    12. <servlet-name>SampleServicePortType</servlet-name>
    13. <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    14. <load-on-startup>1</load-on-startup>
    15. </servlet>
    16. <servlet-mapping>
    17. <servlet-name>SampleServicePortType</servlet-name>
    18. <url-pattern>/SampleService</url-pattern>
    19. </servlet-mapping>
    20. </web-app>
  6. Create the web-archive file and copy it to your tomcat web applications directory.
  7. Edit the startup script for tomcat to include the property : -Dcom.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace=false – This is related to how the soap faults are formatted and is IMPORTANT!
  8. Start tomcat and enjoy!

No comments: