To see the full code for this issue, please see this github
https://github.com/mobiusinversion/web-application
I also created this Jersey Jira
https://java.net/jira/browse/JERSEY-2851
I am working on a ContainerRequestFilter
using Jersey 2.15. This is an embedded Jetty app which is shaded into a single jar.
In the Jetty starter (main class):
public static void main(String[] args) throws Exception {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
Server jettyServer = new Server(10005);
jettyServer.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, ServletConstants.COMPONENT_SCAN_ROOT);
try {
System.out.println("Starting Jetty");
jettyServer.start();
System.out.println("Jetty Started");
jettyServer.join();
} catch (Exception e) {
System.out.println("Could not start server");
e.printStackTrace();
} finally {
jettyServer.destroy();
}
}
I have a filter which is included via a provider
@Provider
public class ExampleProvider implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
ExampleFilter exampleFilter = new ExampleFilter();
featureContext.register(exampleFilter);
}
}
Then in the filter:
public class ExampleFilter implements ContainerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(ExampleFilter.class);
@Context
private HttpServletRequest servletRequest;
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
logger.info("IP ADDRESS " + servletRequest.getRemoteAddr());
// ...
}
}
However this produces a NullPointerException
:
Caused by: java.lang.NullPointerException: null
at com.example.filters.ExampleFilter.filter(ExampleFilter.java:29)
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:131)
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:67)
What am I doing wrong and how do I fix this?
UPDATE: Including pom entried for Jetty and Jersey
<properties>
<jersey.version>2.15</jersey.version>
<jetty.version>9.2.6.v20141205</jetty.version>
</properties>
<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
<!-- Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${jetty.version}</version>
</dependency>
The mistake was that you manually created an instance of
ExampleRequestLoggingFilter
inside theExampleRequestFilterProvider
. Dependency injection only works on instances created and managed by the container itself, such as theExampleRequestFilterProvider
. This explains why@Context
injection didn't seem to work in your manually created instance.A solution would be to move the injection point to the
ExampleRequestFilterProvider
and then pass it through to the constructor ofExampleRequestLoggingFilter
.I tested it here (kudos to the Git project!) and it worked for me.
Note that you're here not passing the actual
HttpServletRequest
instance, but a container managed proxy which delegates further to the actual instance on every method call, so there's nothing to worry as to integrity and threadsafety here.