Web Service – Spring/JAX-WS Example

This post contains notes on how to deploy a web service with Spring Dependency Injection on the Apache Geronimo Application Server. It is not a step-by-step tutorial, but does include the full source.

Source download: webservice-1.0

Software

Requirements:

  • Java JDK 1.6
  • Apache Maven 2
  • Apache Geronimo 2.1 (Jetty)
  • Eclipse 3.4.2 Ganymede
  • Geronimo v21 Server Tools Eclipse Integration

Optional:

  • Sonatype Nexus
  • Maven 2 Eclipse Integration
  • Subversion

Getting Started

This project was started using the maven-archetype-webapp template which generates a basic file structure and pom.xml file:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate
 -DgroupId=com.chibidungeon.test -DartifactId=webservice
 -DarchetypeArtifactId=maven-archetype-webapp
 -DarchetypeGroupId=org.apache.maven.archetypes

To get the webservice to work  jax-ws and spring dependencies were added to the pom.xml:

  • spring-2.5.6
  • spring-core-2.5.6
  • spring-beans-2.5.6
  • spring-context-2.5.6
  • spring-context-support-2.5.6
  • spring-web-2.5.6
  • spring-aspects-2.5.6
  • jaxws-rt-2.1.3
  • jaxws-spring-1.8

Note:  For some reason the spring bundle was required in addition to the separate components; something to do with the xsd schemas.

The pom.xml also needed to be configured to use version 1.6 of the jdk, by adding the following to the build profile:

...
<build>
...
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<configuration>
				<source>1.6</source>
				<target>1.6</target>
			</configuration>
		</plugin>
	</plugins>
...
</build>

Moving to Eclipse

The following maven command will generate the required Eclipse project files:

mvn -Dwtpversion=2.0 eclipse:eclipse

Note:  This command needs to be run after any changes to the pom.xml dependencies.
It may be necessary to run the following command first if dependencies are removed or versions are changed:

mvn eclipse:clean

The project can now be imported into the Eclipse Workspace.

Configuring the Web Service

web.xml – Deployment Descriptor

...
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<servlet>
    <servlet-name>jaxws-servlet</servlet-name>
    <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSSpringServlet
    </servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>jaxws-servlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
...

applicationContext.xml – Spring Config

...
<context:spring-configured />
<context:annotation-config />
<wss:binding url="/hello" service="#helloServicePortType"></wss:binding>
<ws:service id="helloServicePortType" bean="#helloServicePortTypeImpl"></ws:service>
<bean id="helloServicePortTypeImpl" class="com.chibidungeon.test.webservice.HelloServicePortTypeImpl"></bean>
<bean id="greetService" class="com.chibidungeon.test.logic.GreetServiceImpl"></bean>
...

Constructing the Web Service

If you add all the WebMethod and WebParam annotations to the interface, then you don’t need to add them to the implementation.

HelloServicePortType.java – Web Service Interface

package com.chibidungeon.test.webservice;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

@WebService(portName="HelloServicePort")
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public interface HelloServicePortType {
	@WebMethod
	String sayHello(@WebParam(name="name")String name);
}

HelloServicePortTypeImpl.java – Web Service Implementation

package com.chibidungeon.test.webservice;

import javax.jws.WebService;
import org.springframework.beans.factory.annotation.Autowired;
import com.chibidungeon.test.logic.GreetService;

@WebService(serviceName = "HelloService"
    , endpointInterface = "com.chibidungeon.test.webservice.HelloServicePortType"
    , portName = "HelloServicePort")
public class HelloServicePortTypeImpl implements HelloServicePortType {

	@Autowired
	private GreetService greetService;

	public String sayHello(String name) {
		return greetService.getGreeting(name);
	}

}

Geronimo

Geronimo will automatically detect web service annotations and deploy by default. Unfortunately these services know nothing about Spring dependency injection, and should be disabled

Add this line to the Server VM Arguments to turn off web service detection:

-Dorg.apache.geronimo.jaxws.builder.useSimpleFinder=true

For  jax-ws with spring dependency injection to work, certain libraries that come with Geronimo need to be blocked by changing the Deployment Descriptor.

geronimo-web.xml – Geronimo Deployment Descriptor

...
<dep:hidden-classes>
    <dep:filter>org.springframework.</dep:filter>
    <dep:filter>META-INF/spring</dep:filter>
    <dep:filter>com.sun.xml.</dep:filter>
</dep:hidden-classes>
...

References

http://jgeeks.blogspot.com/2008/09/exposing-jax-ws-web-service-using.html

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>

Leave a Reply