@WebServlet annotation doesn’t work with Tomcat 8

I got it working. I had to extend the way I started my Tomcat 8.0.12 server.

Nevertheless, there are three main things that must be done:

  1. web-app version in web.xml has to be at least 3.0 (I used 3.1)
  2. metadata-complete in web.xml may not be true (default is "false")
  3. classes directories have to be added to the embedded Tomcat before start

Here is an example for the web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
  version="3.1" 
  metadata-complete="false"  
  xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

</web-app>

This is how my Tomcat main class looks like (which supports now @WebServlet annotations):

public static void main(String[] args) throws Exception {
  String contextPath = "https://stackoverflow.com/";
  String webappDirLocation = "src/main/webapp/";
  String baseDirectory = new File(webappDirLocation).getAbsolutePath();

  Tomcat tomcat = new Tomcat();
  tomcat.setPort(8080);
  StandardContext context = (StandardContext) tomcat.addWebapp(contextPath, baseDirectory);

  // Additions to make @WebServlet work
  String buildPath = "target/classes";
  String webAppMount = "/WEB-INF/classes";

  File additionalWebInfClasses = new File(buildPath);
  WebResourceRoot resources = new StandardRoot(context);
  resources.addPreResources(new DirResourceSet(resources, webAppMount, additionalWebInfClasses.getAbsolutePath(), contextPath));
  context.setResources(resources);
  // End of additions

  tomcat.start();
  tomcat.getServer().await();
}

Leave a Comment