Announcement Announcement Module
Collapse
No announcement yet.
JAX-WS class doesn't autowire my Bean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JAX-WS class doesn't autowire my Bean

    Hello,

    my intention is to inject a Bean with the @Autowire annotation to a JAX-WS Annotiated class.
    This is working for a normal pring WS approach (@Controller / @RequestMapping) but not for the JAX-WS part.

    My container is a Tomcat 6 instance and Spring 3.0.5.

    My code is the following.
    Bean:
    Code:
    package empty.beans;
    
    public class MyBean {
    
    	private String name = "init";
    	private int counter = 0;
    
    	public String getName() {
    
    		return name;
    	}
    	public void setName(String name) {
    
    		this.name = name;
    	}
    	public int getCounter() {
    	
    		return counter;
    	}
    	public void setCounter(int counter) {
    	
    		this.counter = counter;
    	}
    }
    Appconfig:
    Code:
    package empty.configuration;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import empty.beans.MyBean;
    
    @Configuration
    public class AppConfig {
    
    	MyBean myBean;
    
    	public @Bean
    	MyBean myBean() {
    
    		if (myBean == null) {
    			myBean = new MyBean();
    		}
    		return myBean;
    	}
    }
    JAX-WS:
    Code:
    package empty.ws;
    
    import javax.jws.WebMethod;
    import javax.jws.WebResult;
    import javax.jws.WebService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import empty.beans.MyBean;
    
    @WebService(serviceName = "MyService", portName = "MyPort")
    public class TestWS {
    	
    	@Autowired
    	MyBean myBean;
    	
    	@WebMethod(operationName="testBean")
    	@WebResult(name = "ret")
    	public String xxx() {
    		
    		return "yeah, myBean != null " + (myBean != null);
    	}
    }
    Returns me every time that myBean is null.

    A Spring WS:
    Code:
    package empty.ws;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import empty.beans.MyBean;
    
    @Controller
    @RequestMapping(value="/springws")
    public class SpringWS {
    
    	@Autowired
    	MyBean myBean;
    	
    	@RequestMapping(method=RequestMethod.GET)
    	public @ResponseBody String getAllParameter() {
    		
    		myBean.setCounter(myBean.getCounter()+1);
    		return String.valueOf(myBean.getCounter());
    	}
    }
    Returns 1,2,3,4,5,.....

    web.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app 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"
    	version="2.4">
    
    	<display-name>--------</display-name>
    
    	<listener>
    		<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    	</listener>
    
    	<!-- Startup listener for Spring -->
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    
    	<!-- Dispatcher servlet for Spring -->
    	<servlet>
    		<servlet-name>dispatcher</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>/WEB-INF/applicationContext.xml</param-value>
    		</init-param>
    		<load-on-startup>110</load-on-startup>
    	</servlet>
    
    
    	<servlet>
    		<servlet-name>test-ws</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>dispatcher</servlet-name>
    		<url-pattern>/api/*</url-pattern>
    	</servlet-mapping>
    
    	<servlet-mapping>
    		<servlet-name>test-ws</servlet-name>
    		<url-pattern>/testws</url-pattern>
    	</servlet-mapping>
    </web-app>


    ApplicationContext.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    	<context:component-scan base-package="empty" />
    	<context:annotation-config />
    	<mvc:annotation-driven />
    </beans>

    thanks in advance.

  • #2
    Where is the annotation telling Spring to dig into this classe on the class TestWS ?
    Putting it in the package scanned by Spring with <context:component-scan base-package="empty" /> is not enough.

    Look at your controller SpringWs, it is working because it have on top of it the annotation @Controller.
    This annotation is telling to Spring : "im a bean ,precisely a controller so please dig into my code to found more (@Autowired...)"
    So add to your classe TestWs either @Repository or @Service

    And verify that you are not missing some jar dependency
    To learn more : http://weblogs.java.net/blog/2007/11...uration-spring

    Comment


    • #3
      Still does not work, even if I use one of the annotions and include SpringBeanAutowiringSupport.

      If some one would try it on his machine this is the pom.xml

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      	<modelVersion>4.0.0</modelVersion>
      	<groupId>me</groupId>
      	<artifactId>ws-test</artifactId>
      	<packaging>war</packaging>
      	<version>1.0</version>
      	<name></name>
      	<url></url>
      
      	<properties>
      		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      	</properties>
      
      	<repositories>
      		<repository>
      			<id>maven2-repository.dev.java.net</id>
      			<name>Java.net Repository for Maven 2</name>
      			<url>http://download.java.net/maven/2/</url>
      		</repository>
      	</repositories>
      
      
      	<dependencies>
      		<dependency>
      			<groupId>javax.servlet</groupId>
      			<artifactId>servlet-api</artifactId>
      			<version>2.4</version>
      			<scope>provided</scope>
      		</dependency>
      		<dependency>
      			<groupId>com.sun.xml.ws</groupId>
      			<artifactId>jaxws-rt</artifactId>
      			<version>2.2.1</version>
      		</dependency>
      		<dependency>
      			<groupId>log4j</groupId>
      			<artifactId>log4j</artifactId>
      			<version>1.2.8</version>
      			<type>jar</type>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework</groupId>
      			<artifactId>org.springframework.web.servlet</artifactId>
      			<version>3.0.5.RELEASE</version>
      		</dependency>
      
      		<dependency>
      			<groupId>commons-logging</groupId>
      			<artifactId>commons-logging</artifactId>
      			<version>1.1</version>
      		</dependency>
      				<dependency>
      			<groupId>cglib</groupId>
      			<artifactId>cglib-nodep</artifactId>
      			<version>2.2</version>
      		</dependency>
      
      	</dependencies>
      	<!-- Spring -->
      
      	<build>
      		<finalName>testws</finalName>
      		<plugins>
      			<plugin>
      				<groupId>org.apache.maven.plugins</groupId>
      				<artifactId>maven-eclipse-plugin</artifactId>
      				<configuration>
      					<wtpversion>2.0</wtpversion>
      				</configuration>
      			</plugin>
      			<plugin>
      				<groupId>org.apache.maven.plugins</groupId>
      				<artifactId>maven-compiler-plugin</artifactId>
      				<version>2.1</version>
      				<configuration>
      					<source>1.6</source>
      					<target>1.6</target>
      				</configuration>
      			</plugin>
      		</plugins>
      	</build>
      	<pluginRepositories>
      		<pluginRepository>
      			<id>maven2-repository.dev.java.net</id>
      			<url>http://download.java.net/maven/2/</url>
      		</pluginRepository>
      	</pluginRepositories>
      
      </project>

      Comment


      • #4
        And where is spring-context jar & eventually spring-core?
        Try with spring-context & if it is not working, add spring-core but im almost certain that you are missing spring-context because this contains class like :
        ClassPathScanningCandidateComponentProvider (A component provider that scans the classpath from a base package).


        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        </dependency>
        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
        </dependency>

        Comment


        • #5
          Although including this libs seperatly does not help.
          If I deploy the war in JBoss 6 instead of Tomcat 6 I got:

          Code:
          14:29:32,060 INFO  [STDOUT] 2011-01-17 14:29:32,059 DEBUG: SpringBeanAutowiringSupport - Current WebApplicationContext is not
           available for processing of TestWS: Make sure this class gets constructed in a Spring web application. Proceeding without in jection.
          Anyway, there is a closed bug ticket for Weblogic server that say Injection in JAX-WS isn't working.
          Is here someone that used autowiring support in JAX-WS project on an actual Tomcat?

          Comment


          • #6
            Doesn't work in Glassfish either.

            Comment


            • #7
              Had my Tomcat logger wronmg configured, having this error on the log also:

              Code:
              DEBUG: org.springframework.web.context.support.SpringBeanAutowiringSupport [main] - [89] Current WebApplicationContext is not available for processing of TestWS: Make sure this class gets constructed in a Spring web application. Proceeding without injection.

              What do I wrong?

              Comment


              • #8
                Originally posted by backToMoon View Post
                Had my Tomcat logger wronmg configured, having this error on the log also:

                Code:
                DEBUG: org.springframework.web.context.support.SpringBeanAutowiringSupport [main] - [89] Current WebApplicationContext is not available for processing of TestWS: Make sure this class gets constructed in a Spring web application. Proceeding without injection.

                What do I wrong?
                This error message dissoccurs if I remove SpringBeanAutowiringSupport from the extend list of the TestWS class.

                Comment


                • #9
                  Post your project here (the minimal version with the problem) (rapidhsare, megaupload or whatever)
                  im gonna debug it. Yeah it is E-christhmas

                  Comment


                  • #10
                    I found the solution to this issue

                    You need to put Spring listener org.springframework.web.context.ContextLoaderListe ner before the Web Services listener com.sun.xml.ws.transport.http.servlet.WSServletCon textListener

                    Comment


                    • #11
                      Originally posted by lucasam View Post
                      I found the solution to this issue

                      You need to put Spring listener org.springframework.web.context.ContextLoaderListe ner before the Web Services listener com.sun.xml.ws.transport.http.servlet.WSServletCon textListener
                      Even with this configuration I'm still having this problem. Any suggestions?

                      GlassFish 3.1
                      Spring 3.0.5.RELEASE

                      Comment


                      • #12
                        On Websphere I believe this to be a problem with the websphere JAX-WS engine instantiating the Web service endpoints instead of getting them from the Spring container. You can see this by adding a breakpoint in the constructor, or even better in one of the setters for any spring wired bean in your Web Service IMPL class. You can see that Spring will initialize the beans and yet they will be null when accessed after a web service call. This leads me to believe that they are not the same bean.

                        So in effect the bean properties are getting wired but the instance of the impl being used by WebSphere (or I would assume Glassfish) is not.

                        One solution would be to make the impl ApplicationContextAware and use a static ApplicationContext. Then you can access any bean in the context using the GetBean methods made available via the static context.

                        Comment

                        Working...
                        X