title: Vaadin 22 with web.xml and Spring
body: <p>I have a working Vaadin 18 prototype that uses web.xml and Spring.</p>
  <p>The prototype is for a port of a large webapp that uses web.xml and vanilla Spring.
  I want to update the front-end without dropping web.xml or using Spring Boot.</p>
  <p>It works fine in Vaadin 18.0.6, but fails on startup in Vaadin 22.0.0 with:</p>
  <pre><code>java.lang.IllegalStateException: The application Lookup instance is not found in the interface com.vaadin.flow.server.VaadinContext instance. It means that the container has not executed Lookup initialization code: so either the container is not Servlet 3.0 compatible or project configuration is broken.
      at com.vaadin.flow.server.startup.ApplicationConfiguration.lambda$get$0 (ApplicationConfiguration.java:58)
      at com.vaadin.flow.server.VaadinServletContext.getAttribute (VaadinServletContext.java:73)
      at com.vaadin.flow.server.startup.ApplicationConfiguration.get (ApplicationConfiguration.java:50)
  </code></pre>
  <p>Initial digging suggests that the <strong>disable.automatic.servlet.registration</strong> context parameter is no longer supported.</p>
  <p>What is required to get the prototype working in Vaadin 22?</p>
  <p>Here is the web.xml:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
  &lt;web-app xmlns=&quot;http://xmlns.jcp.org/xml/ns/javaee&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd&quot;
       version=&quot;3.1&quot;
       metadata-complete=&quot;false&quot;&gt;
  
  &lt;!-- NOTE: metadata-complete=&quot;false&quot; is required, in order to invoke
             ClassLoaderAwareServletContainerInitializer subclasses (DevModeInitializer etc) --&gt;
  
  &lt;context-param&gt;
      &lt;!-- disables registration of the VaadinServlet. This is required as it is registered via AppServlet --&gt;
      &lt;param-name&gt;disable.automatic.servlet.registration&lt;/param-name&gt;
      &lt;param-value&gt;true&lt;/param-value&gt;
  &lt;/context-param&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;servlet&gt;
      &lt;servlet-name&gt;AppServlet&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.example.AppServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;
  
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;AppServlet&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/app&lt;/url-pattern&gt;
      &lt;url-pattern&gt;/app/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  
  &lt;/web-app&gt;
  </code></pre>
  <p>And the corresponding servlet:</p>
  <pre><code>/**
   * Servlet to wire Vaadin into web.xml.
   */
  public class AppServlet extends HttpServlet {
  
      private SpringServlet delegate;
  
      @Override
      public void init(ServletConfig config) throws ServletException {
          super.init(config);
          ServletContext servletContext = getServletContext();
          WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
          delegate = new SpringServlet(context, false);
          delegate.init(config);
      }
  
      @Override
      public void destroy() {
          if (delegate != null) {
              delegate.destroy();
          }
      }
  
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
          delegate.service(request, response);
      }
  }
  </code></pre>