title: Spring-mvc + Spring-Security + Thymeleaf - Error Resolving Template
body: <p>I'm following a simple online tutorial for building a Spring + Spring Security + Thymeleaf + Maven project and I'm getting the following error:</p>
  
  <pre><code>[ERROR] [tomcat-http--4 02:00:16] (TemplateEngine.java:process:1085) [THYMELEAF][tomcat-http--4] Exception processing template "login": Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers
  Feb 24, 2015 2:00:16 PM org.apache.catalina.core.StandardWrapperValve invoke
  SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/hub] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause
  org.thymeleaf.exceptions.TemplateInputException: Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers
  at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246)
  at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104)
  at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
  at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011)
  at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335)
  at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190)
  at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
  at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
  at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
  at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
  at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
  at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
  at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:146)
  at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:279)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>It looks like for some reason it is not resolving the login page but even though the login page is at the correct location. If I point to the users.html page that page loads and there are no errors. Must be something very simple I'm missing out on. Can someone please assist?</p>
  
  <p>The following are my config classes:</p>
  
  <pre><code>public class ApplicationInitializer implements WebApplicationInitializer {
  
  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
      //Load application context
      AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
      rootContext.register(ApplicationContext.class);
      rootContext.setDisplayName("hub");
  
      //Context loader listener 
      servletContext.addListener(new ContextLoaderListener(rootContext));
  
      //Dispatcher servlet
      ServletRegistration.Dynamic dispatcher = 
              servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
      dispatcher.setLoadOnStartup(1); 
      dispatcher.addMapping("/");
  }
  
  }
  </code></pre>
  
  <p>ApplicationContext class:</p>
  
  <pre><code>@Configuration 
  @ComponentScan(basePackages = {"com.motodoc.hub.*"})
  @EnableWebMvc
  @Import({SpringDataConfig.class, ThymeleafConfig.class, SecurityConfig.class})
  @ImportResource("classpath:trace-context.xml")
  @PropertySource("classpath:spring.properties")
  public class ApplicationContext extends WebMvcConfigurerAdapter {
  
  // Maps resources path to webapp/resources
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
  }
  
  // Only needed if we are using @Value and ${...} when referencing properties
  @Bean
  public static PropertySourcesPlaceholderConfigurer properties() {
      PropertySourcesPlaceholderConfigurer propertySources = new PropertySourcesPlaceholderConfigurer();
      Resource[] resources = new ClassPathResource[] { 
              new ClassPathResource("spring.properties") };
      propertySources.setLocations(resources);
      propertySources.setIgnoreUnresolvablePlaceholders(true);
      return propertySources;
  }
  
  // Provides internationalization of messages
  @Bean
  public ResourceBundleMessageSource messageSource() {
      ResourceBundleMessageSource source = new ResourceBundleMessageSource();
      source.setBasename("messages");
      return source;
  }
  }
  </code></pre>
  
  <p>ThymeleafConfig class:</p>
  
  <pre><code>@Configuration 
  public class ThymeleafConfig {
  
  @Bean 
  public ServletContextTemplateResolver templateResolver() {
      ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".html");
      resolver.setTemplateMode("HTML5");
      resolver.setOrder(1);
      return resolver;
  }
  
  @Bean 
  public SpringTemplateEngine templateEngine() {
      SpringTemplateEngine engine = new SpringTemplateEngine();
      engine.setTemplateResolver(templateResolver());
      return engine;
  }
  
  @Bean 
  public ThymeleafViewResolver thymeleafViewResolver() {
      ThymeleafViewResolver resolver = new ThymeleafViewResolver();
      resolver.setTemplateEngine(templateEngine());
      return resolver;
  }   
  }
  </code></pre>
  
  <p>SpringSecurityConfig class:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("mkyong").password("123456").roles("USER");
    auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
    auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
  }
  
  @Override
  public void configure(WebSecurity web) throws Exception {
      web.ignoring().antMatchers("/resources/**");
    }
  
  @Override
  protected void configure( HttpSecurity http ) throws Exception
  {
      http
          .authorizeRequests()
          .antMatchers("/**").authenticated()
          .antMatchers("/resources/**").permitAll()
          .anyRequest().authenticated()
          .and()
      .formLogin()
          .loginPage("/login")
          .permitAll()
          .defaultSuccessUrl("/users")
          //.failureUrl("/login.html?authfailed=true")
          .and()
      .logout()
          .invalidateHttpSession(true)
          .logoutUrl("/logout")
          .deleteCookies("JSESSIONID")
          .logoutSuccessUrl("/");
  }
  }
  </code></pre>
  
  <p>SecurityInit class:</p>
  
  <pre><code>public class SecurityInit extends AbstractSecurityWebApplicationInitializer {
  
  }
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/M5y50.png" alt="Screenshot of project folders and files"></p>