users@jersey.java.net

Re: Spring jersey request scope issue

From: Philip Verdemato <philip.verdemato_at_gmail.com>
Date: Tue, 18 May 2010 18:44:12 +0100

Hi,

I have an issue with unit testing some request scoped jersey calls.

My ACResource class gets picked up fine by spring:


@Path("/{accType}/{acc}")
@Component
@Scope("request")
public class ACResource {
    // The Java method will process HTTP GET requests
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public MappingsBean getAccession(@PathParam("accType") String
accType, @PathParam("acc") String acc) {
         System.out.println("Getting JSON");
        MappingsBean mb = new MappingsBean();
        mb.add(accType,acc);
        return mb;
    }
}

But when it runs the unit test, it gives me the following error:

SEVERE: service exception:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'ACResource': Scope 'request' is not active
for the current thread; consider defining a scoped proxy for this bean
if you intend to refer to it from a singleton; nested exception is
java.lang.IllegalStateException: No thread-bound request found: Are
you referring to request attributes outside of an actual web request,
or processing a request outside of the originally receiving thread? If
you are actually operating within a web request and still receive this
message, your code is probably running outside of
DispatcherServlet/DispatcherPortlet: In this case, use
RequestContextListener or RequestContextFilter to expose the current
request.
       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)


The unit test code I use is:

public class ACResourceTest extends JerseyTest {

   public ACResourceTest() throws Exception {
           super(new WebAppDescriptor.Builder("com.phil.ie.acmap.resources")
               .contextPath("AccMapper")
               .contextParam("contextConfigLocation",
"classpath:applicationContext.xml")
               .servletClass(SpringServlet.class)
               .contextListenerClass(ContextLoaderListener.class)
               .build());

       System.out.println("SETUP OK--------");
   }

   @Test
   public void testAccGet() {

         WebResource webResource = resource();
       String responseMsg =
webResource.path("XYZ").path("ZZZ").accept(MediaType.APPLICATION_JSON).get(String.class);
       assertTrue( responseMsg.length() > 0);
  }
}

The resource() call in testAccGet() works, and then it produces the error.

I'm guessing that Spring is not initialising the Bean right. If I
change the @Scope on ACResource to 'singleton' it works.
Does anyone have any idea what I am doing wrong ?
Here are my maven deps:


 <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-server</artifactId>
       <version>1.2</version>
   </dependency>
   <dependency>
       <groupId>com.sun.jersey.contribs</groupId>
       <artifactId>jersey-spring</artifactId>
       <version>1.2</version>
   </dependency>
  <dependency>
       <groupId>com.sun.jersey.jersey-test-framework</groupId>
       <artifactId>jersey-test-framework-grizzly</artifactId>
       <version>1.2</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>com.sun.jersey.jersey-test-framework</groupId>
       <artifactId>jersey-test-framework-external</artifactId>
       <version>1.2</version>
       <scope>test</scope>
   </dependency>


My application context looks like:

 <context:component-scan base-package="com.phil.ie.acmap.resources"/>


My web.xml contains:

 <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>
     <listener>
         <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
    <servlet>
      <servlet-name>AccMapper</servlet-name>
      <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>AccMapper</servlet-name>
      <url-pattern>/*</url-pattern>
    </servlet-mapping>

Many thanks in advance,

Phil