JAX WS webservice does not take spring bean from applicationcontext, hence throws null pointer exception
Asked Answered
R

6

6

Hi I have got the webservice up and running , i have used jax ws. I have used Spring to be able to use beans with Autowired and stuff that spring gives like property value injection in applicationContext.xml.

I have the below spring applicationcontext.xml entry:

<context:component-scan base-package="com.mybeans.service" />      
<bean  id="myProperty" class="com.mybeans.service.MyBeanProperty"
p:Size="BIG">
</bean>

In web service end point class , i have done:

@Autowired private MyBeanProperty myProperty;

And I have a method :

public String getSize() {

return myProperty.getSize();

}

Unfortunately when i invoke the method it does not get any value and throws nullpointerexception.

PS: I used soapUI to run the wsdl of the webservice and invoked the method.

Is the webservice runs before the beans get created by Spring??


To duffmo

Yes i used component scan in applicationContext. And i do have the context loader listener as below in web.xml. Please help me..

Here is my complete code explainaton with code

I am using JAX-WS and Spring and try to setup a few WebServices which need run on Tomcat 7. I am using Maven as build tool therefore I just list my two dependencies here:

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>3.0.5.RELEASE</version>
   </dependency>

     <dependencies>
    <dependency>
      <groupId>com.sun.xml.ws</groupId>
      <artifactId>jaxws-rt</artifactId>
      <version>2.1.3</version>
    </dependency>

    </dependencies>

my service classes are located in com.test.services and are named TestService & HelloWorldService and look as follows:

package com.test.services;

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

@WebService( name = "Test", serviceName = "TestService" )
public class TestService {

  @WebMethod
  public String getTest() {
    return "Test";
  }

}

this is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>toolbox</display-name>
  <description>testing webservices</description>
  <listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>jaxws-servlet</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>jaxws-servlet</servlet-name>
    <url-pattern>/testservice</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>jaxws-servlet</servlet-name>
    <url-pattern>/helloworldservice</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>10</session-timeout>
  </session-config>
</web-app>

and this is my sun-jaxws.xml:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name="jaxws-servlet"
        implementation="com.test.services.TestService"
        url-pattern="/testservice"/>
    <endpoint
        name="jaxws-servlet"
        implementation="com.test.services.HelloWorldService"
        url-pattern="/helloworldservice" />
</endpoints>

This works great and I can access the services by pointing my browser to [url]http://localhost:8080/toolbox/testservice[/url] respectively [url]http://localhost:8080/toolbox/helloworldservice[/url]. However Spring support is obviously not activated.

I tried the following which just leaver the HelloWorldService available: web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>toolbox</display-name>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

and applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:task="http://www.springframework.org/schema/task"
  xsi:schemaLocation="
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
  <context:component-scan base-package="com.test.services" />
  <bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
    <property name="baseAddress" value="http://localhost:8080/" />
  </bean>
 </beans>

furthermore I annotated both Service classes with @Service annotation. As I mentioned before, this only publishes the alphabetically first webservice, hence HelloWorldService. Also it changes the URL, as the service is now available as [url]http://localhost:8080/[/url] rather than [url]http://localhost:8080/toolbox/helloworldservice[/url]. The logging of Tomcat shows, that the Spring Context loads both Classes as Spring beans. Do you have any ideas or suggestions on how to enable Spring support while keeping both services available??

Ricoriki answered 23/9, 2012 at 19:49 Comment(0)
F
6

It is answered here. Ultimately nothing worked other than adding below code to service impl.

    @PostConstruct
public void init() {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
Fulfil answered 1/12, 2013 at 16:8 Comment(0)
H
5

No Need to use ApplicationContext as well, if you do the following things

  1. Annotate your service class with @Service
  2. Service class should extends "SpringBeanAutowiringSupport".

Please have a look at the following snippet.

@org.springframework.stereotype.Service
@javax.jws.WebService (endpointInterface="a.b.c.MyPort", 
            targetNamespace="http://a.b.co.in/Retail/MyService/V1", 
            serviceName="MyService", 
            portName="MyServicePort", 
            wsdlLocation="wsdl/MyService.wsdl")
public class MyServiceBindingImpl extends org.springframework.web.context.support.SpringBeanAutowiringSupport{
Hyperaemia answered 2/10, 2012 at 9:45 Comment(2)
Will this create the bean as a singleton or an object per request?Mllly
It will create singleton objectHyperaemia
O
3

I got the same issue, to resolve it I started the jaxws listener after the spring listener:

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>

Hope it helps

Ogilvie answered 21/1, 2013 at 10:44 Comment(0)
H
2

Your TestService (which is annotated with @WebService) should extend "SpringBeanAutowiringSupport" class to kick start spring binding.

Please have a look at the duffmo mentioned points as well.

Hyperaemia answered 25/9, 2012 at 14:23 Comment(1)
It got working great now, thanks. @Autowired still did not work but component-scan works , so i did a work around with using the Application context and calling the getBean("<ben id>") method.Ricoriki
R
0

I think it's more likely that your Spring context has not be loaded and made available to the web service. How have you done that?

You should have a ContextLoaderListener configured in the web.xml for the WAR in which the web service is deployed. Did you tell it where to load the Spring context? Are you using component scan?

http://renidev.wordpress.com/2009/02/02/how-to-use-springs-context-component-scan-and-annotation/

Recapture answered 23/9, 2012 at 19:52 Comment(0)
T
0

You misses the configuration for webservice inject. So put more inside the web.xml

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>

Please don't forget the order. Because you need to init the bean for the autowired field first

Thanks

Tosh answered 16/8, 2019 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.