users@jersey.java.net

[Jersey] Re: How to access a Spring bean from Jersey resource?

From: Srinivas Naresh Bhimisetty <shri.naresh_at_gmail.com>
Date: Thu, 7 Apr 2011 10:30:34 +0530

Frederic,

  the InMemoryTestContainer would not be able to run Spring based tests.
Please try using one of the following test container types:
1. GrizzlyWeb, (or)
2. EmbeddedGlassFish, (or)
3. External Test Container

- Naresh

On Thu, Apr 7, 2011 at 8:58 AM, Frederic Bergeron
<FBergeron_at_rocketmail.com>wrote:

> Hmmm, it seems that the Spring beans are never instanciated. I put a trace
> in my bean's constructor and it's never shown.
>
> As in the Spring Annotations example, my test class looks like this:
>
> public class RESTAPITest extends JerseyTest {
>
> public RESTAPITest() throws Exception {
> super( new WebAppDescriptor.Builder( "resource" ).
> contextPath( "/" ).
> contextParam( "contextConfigLocation",
> classpath:properties/servlet-applicationContext.xml" ).
> servletClass( SpringServlet.class ).
> contextListenerClass( ContextLoaderListener.class ).build());
> }
>
> ...
>
> }
>
> I was expecting that referring to SpringServlet class would trigger the
> beans instanciation but after putting a trace in SpringServlet, I know that
> the SpringServlet class is not even loaded.
>
> So, how can Spring beans can be instanciated? Is it even possible to do so
> using the InMemoryTestContainerFactory?
>
> Frederic Bergeron
>
>
> --- On Wed, 4/6/11, Frederic Bergeron <FBergeron_at_rocketmail.com> wrote:
>
> From: Frederic Bergeron <FBergeron_at_rocketmail.com>
> Subject: [Jersey] Re: How to access a Spring bean from Jersey resource?
> To: users_at_jersey.java.net
> Date: Wednesday, April 6, 2011, 11:53 PM
>
> Hi Tauren,
>
> Thanks for your quick reply. Your solution works when I'm using the real
> servlet but for some reasons, it doesn't work in my unit tests when I use
> the InMemoryTestContainerFactory.
>
> The error I got is this one:
>
> --- BEGIN OUTPUT ---
> INFO: Initiating Jersey application, version 'Jersey: 1.6 04/06/2011 10:19
> PM'
>
> Apr 6, 2011 10:30:36 PM com.sun.jersey.spi.inject.Errors
> processErrorMessages
>
> SEVERE: The following errors and warnings have been detected with resource
> and/or provider classes:
> SEVERE: Missing dependency for field: private ItemImpl
> resource.MyResource.item
>
> Apr 6, 2011 10:30:36 PM
> com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer
> stop
>
> INFO: Stopping low level InMemory test container
> --- END OUTPUT ---
>
> I've put
> some traces in Jersey code (1.6) and the error occurs in
> com.sun.jersey.server.spi.component.ResourceComponentInjector in the
> processFields() method. In the for loop that process the parameters, the
> InjectableScopePair isp is null and that's what triggers the error. I don't
> understand why though.
>
> Anyone has an idea?
>
> Regards,
>
> Frederic Bergeron
>
> --- On Tue, 4/5/11, Tauren Mills <tauren_at_groovee.com> wrote:
>
> From: Tauren Mills <tauren_at_groovee.com>
> Subject: Re: [Jersey] How to access a Spring bean from Jersey resource?
> To: users_at_jersey.java.net
> Cc: "Frederic Bergeron" <FBergeron_at_rocketmail.com>
> Date: Tuesday, April 5, 2011, 7:36 PM
>
> Frederic,
> Add an @Component annotation to your resource class and then use
> @InjectParam to
> inject your beans:
> @Component_at_Path("/resource")public class MyResource {
>
>
> @InjectParam private MySpringBean bean;
> @GET public Response doGet() { bean.getSomething() // ... }
>
> }
> Your Spring configuration XML will need something like this in it:
> <!-- Enable annotation configuration -->
> <context:annotation-config/>
>
>
> <context:component-scan base-package="com.company.rest.resources"/>
> I might have missed something, but I think that's it.
>
>
> Tauren
>
>
> On Tue, Apr 5, 2011 at 2:02 AM, Frederic Bergeron <
> FBergeron_at_rocketmail.com> wrote:
>
>
> Hi,
>
>
>
> I'm implementing a REST API on top of a web application using the Spring
> framework. I managed to implement interoperability between Jersey and
> Spring using the following method:
>
>
>
> @GET
>
> @Produces( MediaType.APPLICATION_XML )
>
> public List<Item> getItems( @Context HttpServletRequest req ) {
>
> HttpSession ses = req.getSession( true );
>
> WebApplicationContext ctxt =
> WebApplicationContextUtils.getWebApplicationContext( ses.getServletContext()
> );
>
> ItemCatalogImpl itemCatalog = (ItemCatalogImpl)ctxt.getBean(
> "itemCatalog" );
>
>
>
> ...
>
> }
>
>
>
> My Jersey resource is able to access successfully a bean that has been
> instanciated by Spring. Yeah!
>
>
>
> However now, I would like to implement unit tests for my REST API using
> InMemoryTestContainerFactory. My solution fails when using
> InMemoryTestContainerFactory. I think the InMemoryTestContainerFactory is
> not able to instanciate/simulate the HttpServletRequest and I cannot access
> the servlet context that is required to get the WebApplicationContext.
>
>
>
>
>
> Is there another way for my Jersey resource to access a Spring bean in both
> situations (real servlet and InMemoryTestContainerFactory)? I suspect that
> there are many ways to do it but when I google about that, I'm a bit lost.
> I have seen references to @Component, @Inject, @Autowire, and
> SpringServlet. I have also seen that @Inject is deprecated in the 1.6's
> javadoc. Which way is the best? Any good links on this topic?
>
>
>
>
>
> Regards,
>
>
>
> Frederic Bergeron
>
>
>
>
>