How to get a servlet to answer

The basic problem, as illustrated by this somewhat aged Jetty pathSpec documentation, is that "/" is treated as "/*" when giving a servlet path spec. Thus, if you want to have a servlet as "front page" in an embedded scenario:

ServletContextHandler servlets = 
    new ServletContextHandler(ServletContextHandler.SESSIONS);
servlets.addServlet(MyServlet.class, "/");

... that servlet will get requests for the entire URL space and no other servlet in the context will get any requests. In particular, if you want to add a DefaultServlet to serve static web pages, images and CSS, that will be tricky.

The solution is to stick each servlet in its own context handler. If you do this, you can control in what order they are asked to handle the HTTP request. Thus, you can make sure it asks all other servlets before asking the greedy "/" servlet. Something like this:

ServletContextHandler html, servlets;
servlets = new ServletContextHandler(ServletContextHandler.SESSIONS);
servlets.addServlet(MyServlet.class, "/");

html = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder holder = html.addServlet(DefaultServlet.class, "/html/*");
holder.setInitParameter("resourceBase", "./");

ContextHandlerCollection collection = new ContextHandlerCollection();
// First, try the static stuff
// Then ask the greedy servlet

Server server = new Server(8080);

The reason this works is that a context will simply "pass" if it does not match a certain URL.

While on the subject, it is fairly annoying when developing that the context won't print tracebacks. When developing, we would prefer the error web page to contain the stack trace. This can be achieved fairly easily:

ErrorHandler errorHandler = new ErrorHandler();