I am working on upgrading a Vaadin 8 application to Vaadin 14. I had to manually define an extension of VaadinServlet rather than using Vaadin 14's automatic servlet registration, as I need it to be mapped to a specific URL pattern. I am using web.xml to configure the servlet in the same way that it was successfully configured for Vaadin 8.
When my servlet is initialized, I get a ServletException caused by a NullPointerException coming from Vaadin's code. I looked at the source code and I can see that the exception occurs when Vaadin tries to get a Lookup instance from the servlet's ServletContext and instead it returns null. I found that the Lookup instance is supposed to get added to the context in LookupServletContainerInitializer, but it appears that this is not happening in my case.
Does anyone know what might be causing this issue? The stack trace of the NullPointerException is below.
Caused by: java.lang.NullPointerException
    at com.vaadin.flow.server.DeploymentConfigurationFactory.getTokenFileFromClassloader(DeploymentConfigurationFactory.java:341)
    at com.vaadin.flow.server.DeploymentConfigurationFactory.getTokenFileContents(DeploymentConfigurationFactory.java:311)
    at com.vaadin.flow.server.DeploymentConfigurationFactory.readBuildInfo(DeploymentConfigurationFactory.java:181)
    at com.vaadin.flow.server.DeploymentConfigurationFactory.createInitParameters(DeploymentConfigurationFactory.java:174)
    at com.vaadin.flow.server.VaadinServlet.createDeploymentConfiguration(VaadinServlet.java:152)
    at com.vaadin.flow.server.VaadinServlet.createServletService(VaadinServlet.java:190)
    at com.vaadin.flow.server.VaadinServlet.init(VaadinServlet.java:77)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:602)
    ... 28 more 
    