I am deploying a JAX-RS application to JBoss EAP 6.2.
I am trying to obtain a ServletContext from inside of a JAX-RS resource class so that I can read some context-param values that I have set in the WEB-INF/web.xml file.
I.e., after I've gotten hold of the ServletContext I was planning to call ServletContext#getInitParam to get the value.
I am using injection to get the ServletContext as advised here.
The relevant portion of my web.xml is:
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>foo.MyApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/jax-rs/*</url-pattern>
</servlet-mapping>
So I am using RESTEasy which is bundled with JBoss.
Class MyApplication is:
public class MyApplication extends Application {
private Set<Object> singletons = new HashSet<>();
public MyApplication() {
singletons.add( new MyResource() );
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
… and finally in class MyResource I have the following:
@Path(...)
public class MyResource {
@Context
ServletContext context;
public MyResource() {
// I understand context is supposed to be null here
}
// ... but it should have been injected by the time we reach the service method.
@Path("/somePath")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response someMethod( ) {
if (context==null) throw new RuntimeException();
...
}
}
The above code always results in the RuntimeException being thrown. I.e. RESTEasy somehow fails to inject the ServletContext. Note that I don't have any other JAX-RS problems. I.e. if I hardcode the context-param values I was hoping to be able to retrieve via `ServletContext#getInitParameter", then the JAX-RS rest functionality works as expected when the WAR is deployed to JBoss.
Experimenting further I discovered that the ServletContextis only injected if I perform the injection at an argument of the service method like this:
@Path("/somePath")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response someMethod(@Context ServletContext servletContext) {
...
}
… however I would prefer not to change the API. Moreover, I would like to perform some costly initialization based on the context-param value once and for all, not on every service method invocation.
My questions are:
- why is the injection failing?
- I am a little tired of the annotations magic failing at runtime, is there a way to get the
ServletContextwithout using annotations? - Alternatively, is it possible for my
MyApplicationclass to obtain theServletContextand pass it to theMyResourceclass as a constructor parameter? - If all else fails I guess I can always read and parse the web.xml file myself using
Class#getResourceAsStream?