1

Here is how I setup my Jetty server:

Server server = new Server(80);
server.setStopAtShutdown(true);

ServletHandler servletHandler = new ServletHandler();
servletHandler.addServletWithMapping(Erreur500Servlet.class, "/generate-error-500");
servletHandler.addServletWithMapping(AresServlet.class, "/ares/*");
servletHandler.addFilterWithMapping(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));

server.setHandler(servletHandler);
server.start(); // at com.company.MyPoc.init(MyPoc.java:44)
server.join();

However, when it starts, I got the following exception:

2015-10-20 12:53:07,565 (?:?) [WARN] FAILED com.company.filter.RequestLoggingFilter-896472140: java.lang.NullPointerException 
java.lang.NullPointerException: null
    at org.eclipse.jetty.servlet.FilterHolder.doStart(FilterHolder.java:100) ~[jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:753) [jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.servlet.ServletHandler.doStart(ServletHandler.java:183) [jetty-servlet-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89) [jetty-server-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.server.Server.doStart(Server.java:262) [jetty-server-8.0.1.v20110908.jar:8.0.1.v20110908]
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) [jetty-util-8.0.1.v20110908.jar:8.0.1.v20110908]
    at com.company.MyPoc.init(MyPoc.java:44) 

What am I missing?

Jetty 8.0.1.v20110908

Stephan
  • 41,764
  • 65
  • 238
  • 329

2 Answers2

2

First, and most important, Jetty 8 is EOL (End of Life).

Next, please use a more recent version of Jetty, Jetty 8.0.1 is (currently) about 110 releases behind the current stable version of Jetty.

Now, to explain what's going on.

You are using ServletHandler directly, that's an internal class not meant to be instantiated and accessed directly but under the most simplistic and naive of situations. Namely a Server with exactly 1 (and only 1) Servlet, no filters, no security, no session handling, etc...

Use the ServletContextHandler and add your servlets and filters to it. This is the proper way, as it establishes a ServletContext that all of your related Servlets and Filters use to coordinate with.

Example (this is done from memory, as Jetty 8.0.1 is so old, this may need some tweaking to work properly on your ancient version of Jetty):

Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.setResourceBase("/path/to/my/static/resources/");
context.setHandler(server);

context.addServlet(Erreur500Servlet.class, "/generate-error-500");
context.addServlet(AresServlet.class, "/ares/*");
context.addFilter(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
context.addServlet(DefaultServlet.class, "/");

server.start();
server.join();

Of note:

  • If you have static resources to serve (html, javascript, css, images, etc..) then set the base resource path with .setResourceBase(String) (a new, and better, .setBaseResource(Resource) was added in Jetty 9)
  • If you want to serve static resources or get error handling don't forget to call context.addServlet(DefaultServlet.class, "/")

If you want custom error handling, use the ServletContextHandler ErrorHandler features like this

// Default error handler
ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
errorHandler.addErrorPage(500,"/error");

// Your webapp
ServletContextHandler context = new ServletContextHandler();
context.setErrorHandler(errorHandler);
context.addServlet(MyCustomErrorServlet.class, "/error");
// etc ...

Also of note, Jetty ships with a RequestLogHandler, which does the same end goal (but using a Jetty Handler, not via a Filter).

Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136
1

Here is the solution I came up with:

Server server = new Server(80);
server.setStopAtShutdown(true);

ServletContextHandler context = new ServletContextHandler();
context.addServlet(Erreur500Servlet.class, "/generate-error-500");
context.addServlet(AresServlet.class, "/ares/*");
context.addFilter(RequestLoggingFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));

server.setHandler(context);
server.start();
server.join();
Stephan
  • 41,764
  • 65
  • 238
  • 329
  • Don't use the `.add*WithMapping()` methods, use the normal `addServlet()` and `.addFilter()` methods to remain forward compatible. – Joakim Erdfelt Oct 20 '15 at 17:18
  • 1
    Don't forget the `.addServlet(DefaultServlet.class, "/")` otherwise you wont get static content handling, error handling, or dispatcher functionality. – Joakim Erdfelt Oct 20 '15 at 17:20