Hi Dan

Please see comments inline

On Mon, May 9, 2011 at 10:40 PM, Dan Schaffer
<[email protected]> wrote:
> Hi
>
> I'm using CXF 2.4 in a non-spring environment.  I'm unable to get access to
> a fully available version of the ServletContext when I deploy CXF to Tomcat.
>  It works fine for Jetty.  I think there is something I don't understand
> about how CXF plays along with the Tomcat lifecycle.  Here is a snippet of
> my Resource:
>
> @Path("/nevs")
> public class VerificationResource {
>
>        private VerificationEngine verificationEngine;
>
>        private Logger logger =
> Logger.getLogger("nevs.verification_service");
>
>        @Context
>        private ServletContext context;
>
>        public VerificationResource() {
>                logger.info("starting");
>        }
>
>        @Context
>        public void setServletContext(ServletContext context) {
>
> The context is not null. However, a call to context.getAttribute("some key")
> causes a NullPointerException in:
>
> org.apache.cxf.jaxrs.impl.tl.ThreadLocalServletContext.getAttribute(ThreadLocalServletContext.java:46)
>
> I AM able to successfully make the getAttribute call later during a GET.  So
> I could work around this by lazy evaluation.  But I'd rather avoid the
> thread safety issues associated with this approach.
>

The lazy evaluation approach should work fine because ServletContext
will be injected into ThreadLocalServletContext
which is a thread-safe proxy. Singleton resources such as
VerificationResource always have thread local proxies injected.

However, what you can do is to have ServletContext injected as a
constructor argument:

public class VerificationResource {
         public VerificationResource(@Context ServletContext sc) {
         }
}

This will work right now but you'll need to avoid specifying
Application (via the javax.ws.rs.Application parameter) and instead
specify 'VerificationResource' using 'jaxrs.serviceClasses':

<init-param>
  <param-name>jaxrs.serviceClasses</param-name>
  <param-value>
    VerificationResource
  </param-value>

That said, I think with JAX-RS 1.1 one should be able to have the
constructor injection working for Applications too, see more comments
below

> Here is my Application:
>
> public class VerificationApplication extends Application {
>
>        private Set<Object> singletons = new HashSet<Object>();
>        private Set<Class<?>> set = Collections.emptySet();
>
>        public VerificationApplication() {
>                singletons.add(new VerificationResource());
>        }
>
>        @Override
>        public Set<Class<?>> getClasses() {
>                return set;
>        }
>
>        @Override
>        public Set<Object> getSingletons() {
>                return singletons;
>        }
> }
>

public VerificationApplication(@Context ServletContext sc) {
                singletons.add(new VerificationResource(sc));
}

should also work, CXF 2.4.0/2.3.4 supports injecting contexts into
Application instances but no constructor injection is supported - that
needs to be fixed


> Here is my 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>NEVS Development System</display-name>
>  <servlet>
>    <servlet-name>verification_service</servlet-name>
>
>  <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
>      <init-param>
>          <param-name>javax.ws.rs.Application</param-name>
>
>  <param-value>gov.noaa.nevs.servlet.verification_service.VerificationApplication</param-value>
>      </init-param>
>      <load-on-startup>1</load-on-startup>
>  </servlet>
>
>  <servlet-mapping>
>    <servlet-name>verification_service</servlet-name>
>    <url-pattern>/*</url-pattern>
>  </servlet-mapping>
> </web-app>
>
>
> It seems like I need to do something with @PostConstruct or something so
> that I make the getAttribute call later in the lifecycle. However I'm
> drawing a blank.

At the moment either use "jaxrs.serviceClasses" and the constructor
injection or retrieve attributes at the invocation time

Thanks, Sergey

>
> Thanks for any help
>
> Dan
>
>
>
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com

Reply via email to