How to implement JAXWS web services using Spring and Embedded Jetty server?
Dependencies in pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- very important NOTE : if the app is deployed to java 1.6 enviroment, do not forget to add jaxb-api-2.1.jar into endorsed lib path to the jdk otherwise you get an exception like this : java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader so in order to avoid this exception just put jaxb-api-2.1.jar into JAVA6_HOME/lib/endorsed for the dependencies of spring-jaxws please refer to https://jax-ws-commons.dev.java.net/spring/test-app/dependencies.html the url of the web service is :http://localhost:8080/JAXWS_SPRING/testWs-->
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>com.sun.org.apache.xml.internal</groupId>
<artifactId>resolver</artifactId>
<version>20050927</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream</groupId>
<artifactId>sjsxp</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.stream.buffer</groupId>
<artifactId>streambuffer</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>jsr181-api</artifactId>
<version>1.0-MR1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>saaj-api</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
<version>1.0</version>
</dependency>
Defining Jetty server in application-context.xml where spring beans are also defined
To define an embedded jetty server, connector, threadpool and handler properties have to be defined.
given below is the jetty.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Server" class="org.mortbay.jetty.Server" init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="Connector" class="org.mortbay.jetty.nio.SelectChannelConnector">
<property name="port" value="8181" />
</bean>
</list>
</property>
<property name="threadPool">
<bean id="jettyThreadPool" class="org.mortbay.thread.BoundedThreadPool">
<property name="minThreads" value="5" />
<property name="maxThreads" value="10" />
</bean>
</property>
<property name="handler">
<bean id="handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<property name="handlers">
<list>
<bean id="contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
<property name="handlers">
<list>
<bean class="org.mortbay.jetty.webapp.WebAppContext">
<property name="contextPath" value="/JAXWS_SPRING" />
<property name="war" value="./WebContent" />
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</beans>
The issue here is that the property defined as “war” has a value WebContent and this WebContent directory has to be in the project
and within this folder the WEB-INF folder has to be created.
The directory structure of the project has given below.
JAXWS_SPRING
–src
—-resources
——-jetty.xml
——-applicationContext.xml
WebContent
—-WEB-INF
——-web.xml
An advantage of this initialization is that you don’t have to change anything in the project if you want to deploy it to Tomcat server.
When spring is initialized jetty server starts immediately and deploys JAXWS_SPRING into jetty container as specified in the web.xml
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><web-app>
<display-name>JAXWS_SPRING</display-name>
<description>JAXWS_SPRING</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath: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>/testMethod</url-pattern>
</servlet-mapping></web-app>
applicationContext.xml is where the web service is defined. During the deployment of the project,the beans in the application-context.xml are initialized.
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsdhttp://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd">
<wss:binding url="/testMethod">
<wss:service><!-- nested bean is of course fine -->
<ws:service bean="#myService">
<ws:handlers>
<ref bean="myHandler" />
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
<bean id="myService" class="foo.MyService">
<property name="base">
<!-- you can also use propert injection for the service class -->
<value>42</value>
</property>
</bean>
<bean id="myHandler" class="foo.MyHandler" />
</beans>
Sendhil said
I used your applicationContext.xml but still i have problems
==exception
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.sun.xml.ws.transport.http.servlet.SpringBinding’ defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot create inner bean ‘(inner bean)’ while setting bean property ’service’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘(inner bean)’: FactoryBean threw exception on object creation; nested exception is java.lang.ExceptionInInitializerError
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘(inner bean)’: FactoryBean threw exception on object creation; nested exception is java.lang.ExceptionInInitializerError
Caused by: java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at javax.xml.soap.FactoryFinder.newInstance(Unknown Source)
at javax.xml.soap.FactoryFinder.find(Unknown Source)
at javax.xml.soap.SAAJMetaFactory.getInstance(Unknown Source)
at javax.xml.soap.MessageFactory.newInstance(Unknown Source)
at com.sun.xml.ws.api.SOAPVersion.(SOAPVersion.java:178)
at com.sun.xml.ws.api.SOAPVersion.(SOAPVersion.java:83)
at com.sun.xml.ws.api.BindingID.(BindingID.java:318)
at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:294)
at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectFromFactoryBean(AbstractBeanFactory.java:994)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:960)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBeanDefinition(BeanDefinitionValueResolver.java:202)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:955)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:729)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:416)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:290)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:156)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:246)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.IllegalArgumentException: com.sun.xml.messaging.saaj.soap.LocalStrings != com.sun.xml.internal.messaging.saaj.soap.LocalStrings
at java.util.logging.Logger.getLogger(Unknown Source)
at com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl.(Unknown Source)
==
applicationContext.xml
==
42
==
Sendhil said
applicationContext.xml
42
Jonas said
Hello,
i get the following two exceptions with GWT1.7 and embedded jetty:
- ignored XML validation warning org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document ‘http://jax-ws.dev.java.net/spring/servlet.xsd’, because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not .
- org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ‘wss:binding’.
If I deploy the application to tomcat or test the spring-context with testng all is working fine…but not with jetty. Any ideas?
Best Regards,
Jonas