title: Error 404: Issue accessing /WEB-INF/views/sendMessage.jsp. Reason: Not Found
body: <p>I have been struggling with this for hours. I cannot get my simple Jetty + Spring MVC + JSP web application to work.</p>
  
  <p>Here is the directory structure of my project:</p>
  
  <pre><code>spring-form-utf-8-test
  |-- pom.xml
  |-- src
  |   `-- main
  |       |-- java
  |       |   |-- com
  |       |   |   `-- example
  |       |   |       |-- beans
  |       |   |       |   `-- forms
  |       |   |       |       `-- MessageForm.java
  |       |   |       |-- config
  |       |   |       |   `-- WebMvcConfig.java
  |       |   |       `-- controller
  |       |   |           `-- FormController.java
  |       |   `-- Main.java
  |       |-- resources
  |       `-- webapp
  |           |-- images
  |           |   `-- kitty.jpg
  |           `-- WEB-INF
  |               `-- views
  |                   `-- sendMessage.jsp
  `-- target
  </code></pre>
  
  <p>The problem is that when I am trying to access <code>http://localhost:8080</code> I am getting the following error.</p>
  
  <p><img src="https://i.stack.imgur.com/KYLZU.png" alt="Error 404"></p>
  
  <p>I run the server from the command line:</p>
  
  <pre><code>java -jar target\spring-form-utf-8-test-1.0-SNAPSHOT.jar
  </code></pre>
  
  <p>The controller looks like this and I do not see anything wrong with the mapping:</p>
  
  <pre><code>package com.example.controller;
  
  import com.example.beans.forms.MessageForm;
  
  import javax.validation.Valid;
  
  import org.springframework.stereotype.Controller;
  import org.springframework.ui.Model;
  import org.springframework.validation.BindingResult;
  import org.springframework.web.bind.annotation.ModelAttribute;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestMethod;
  
  
  @Controller
  @RequestMapping("/")
  public class FormController {
  
      @ModelAttribute("message")
      public MessageForm createMessageForm() {
          return new MessageForm();
      }
  
      @RequestMapping(method = RequestMethod.GET)
      public String sendForm() {
          return "sendMessage";
      }
  
      @RequestMapping(method = RequestMethod.POST)
      public String processForm(@ModelAttribute("message") @Valid final MessageForm message,
          final BindingResult result,
          final Model model) {
          return "sendMessage";
      }
  }
  </code></pre>
  
  <p>The annotated web application context looks like this</p>
  
  <pre><code>package com.example.config;
  
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.ComponentScan;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  import org.springframework.web.servlet.view.InternalResourceViewResolver;
  
  
  @Configuration
  @ComponentScan("com.example.controller")
  @EnableWebMvc
  public class WebMvcConfig extends WebMvcConfigurerAdapter {
  
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("images/**").addResourceLocations("images/");
      }
  
      @Bean
      public InternalResourceViewResolver setupViewResolver() {
          final InternalResourceViewResolver resolver = new InternalResourceViewResolver();
          resolver.setPrefix("/WEB-INF/views/");
          resolver.setSuffix(".jsp");
  
          return resolver;
      }
  }
  </code></pre>
  
  <p>And the main class which runs the Jetty server instance looks like this.</p>
  
  <pre><code>import java.io.IOException;
  
  import org.eclipse.jetty.server.Server;
  import org.eclipse.jetty.servlet.ServletContextHandler;
  import org.eclipse.jetty.servlet.ServletHolder;
  
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  import org.springframework.web.context.ContextLoaderListener;
  import org.springframework.web.servlet.DispatcherServlet;
  
  public class Main {
      public static void main(String[] args) {
          final Server server = new Server(8080);
          final ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
          servletContextHandler.setErrorHandler(null);
          servletContextHandler.setContextPath("/");
  
          final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
          context.setConfigLocation("com.example.config");
          context.getEnvironment().setDefaultProfiles("dev");
  
          servletContextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), "/*");
          servletContextHandler.addEventListener(new ContextLoaderListener(context));
  
  
          try {
          servletContextHandler.setResourceBase(new ClassPathResource("webapp").getURI().toString());
          } catch (final IOException e) {
              throw new RuntimeException(e);
          }
  
          server.setHandler(servletContextHandler);
          try {
              server.start();
              server.join();
          } catch (final InterruptedException e) {
              throw new RuntimeException(e);
          } catch (final Exception e) {
              throw new RuntimeException(e);
          }
      }
  }
  </code></pre>
  
  <p>Accessing a static resource <code>http://localhost:8080/images/kitty.jpg</code> works without any problem. Also if I change the controller to not be mapped to a view but instead <code>@ResponseBody</code> annotation is used, then I can see the result in the browser.</p>
  
  <p>I have tried to add a <code>org.apache.jasper.servlet.JspServlet</code> instance like it is presented on <a href="http://stas-blogspot.blogspot.de/2013/05/embedding-jetty9-spring-mvc.html" rel="nofollow noreferrer">this blog</a> but this did not bring any results. The error message is the same.</p>
  
  <p>What am I doing wrong here?</p>