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
