Search code examples
javaservletsannotationsjettyembedded-jetty

Embedded Jetty does not find Annotated Servlet


Short: I have a project that provides a war artifact which includes a servlet with annotations but no web.xml. If i try to use the war in jetty i always get only the directory listing of the war content but not the servlet execution.

Any idea?

Long story: My servlets look like this

package swa;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet( asyncSupported = false, urlPatterns={"/*"})
public class ServletX extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Set response content type
        response.setContentType("text/html");

        // Actual logic goes here.
        PrintWriter out = response.getWriter();
        out.println("<h1>Hi there..</h1>");
    }

}

So nothing special i guess. When i use mvn jetty:run everything is fine. After ensuring this the project is packed into a war-archive.

This war archive is used within another project that has to set up jetty within code. This is how its done:

        String jettyPort = properties.getProperty("jetty.port", "8080");
        Server server = new Server();

        ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory());
        httpConnector.setPort(Integer.parseInt(jettyPort));
        httpConnector.setAcceptQueueSize(2);
        httpConnector.setHost("0.0.0.0");
        httpConnector.setIdleTimeout(30000);
        server.setConnectors(new Connector[] { httpConnector });

        WebAppContext wacHandler = new WebAppContext();
        wacHandler.setContextPath("/admin");
        wacHandler.setWar("swa-0.0.1-SNAPSHOT.war");
        wacHandler.setConfigurationDiscovered(true);

        server.setHandler(wacHandler);

        server.start();

When executing this project the logs tell me that the war is found. But if i open the url http://localhost:8080/admin i only see the listing of the war content (instead of 'Hi there').

Can someone point me to my failure?


Solution

  • Updated - Aug 2021

    This process has changed starting in Jetty 10.0.0 (this includes Jetty 11.0.0)

    The existence of the jetty-annotations-<ver>.jar on the classpath is enough to enable the annotation and bytecode scanning for your servlets and websocket layers.

    The WebAppContext.setConfiguration(...) method should no longer be used.

    The old example project has been archived and replaced with

    https://github.com/jetty-project/embedded-servlet-server

    There are examples for ...

    Servlet API Version Jetty Version New Branch
    3.1 Jetty 9.4.x embedded-servlet-server : jetty-9.4.x
    4.0 Jetty 10.x embedded-servlet-server : jetty-10.0.x
    5.0 Jetty 11.x embedded-servlet-server : jetty-11.0.x

    Original Answer - Sept 2014

    You need to define the WebAppContext configurations appropriately (and in the correct order).

        wacHandler.setConfigurations(new Configuration[]
        { 
            new AnnotationConfiguration(), 
            new WebInfConfiguration(), 
            new WebXmlConfiguration(), 
            new MetaInfConfiguration(), 
            new FragmentConfiguration(),
            new EnvConfiguration(), 
            new PlusConfiguration(), 
            new JettyWebXmlConfiguration() 
        });
    

    Don't forget to add the jetty-annotations.jar.

    This is from the EmbedMe.java example for use with Servlet 3.1 found at

    https://github.com/jetty-project/embedded-servlet-3.1/