title: JSTL support in Spring Boot
body: <p>Though I know that there are <a href="http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-jsp-limitations" rel="noreferrer">some limitations in the JSP support</a>, I want to use JSP with JSTL tags in Spring Boot web application.</p>
  
  <p>An extract of my JSP file:</p>
  
  <pre><code>&lt;%@ page pageEncoding="UTF-8"%&gt;
  &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
  &lt;%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%&gt;
  
  ...
  
  &lt;c:catch var="ex"&gt;
      &lt;c:if test="${!fn:contains(param.template,'../') &amp;&amp; !fn:startsWith(param.template,'/')}"&gt;
          &lt;c:import url=    ...
  </code></pre>
  
  <p>So, I added to the following dependencies to pom.xml:</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
      &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
        &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jstl&lt;/artifactId&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>However, If accessing to the jsp, the exception is thrown:</p>
  
  <pre><code>2017-08-14 13:09:32.259 ERROR 2376 --- [nio-8080-exec-2] o.a.c.c.C.[.[localhost].[/].[jsp]        : Servlet.service() for servlet [jsp] in context with path [] threw exception [The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be
   resolved in either web.xml or the jar files deployed with this application] with root cause
  
  org.apache.jasper.JasperException: The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application
          at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:55) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:293) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:80) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTldResourcePath(TagLibraryInfoImpl.java:251) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.TagLibraryInfoImpl.&lt;init&gt;(TagLibraryInfoImpl.java:122) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:434) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:492) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1448) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Parser.parse(Parser.java:145) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:244) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.ParserController.parse(ParserController.java:105) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:203) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Compiler.compile(Compiler.java:374) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Compiler.compile(Compiler.java:351) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.compiler.Compiler.compile(Compiler.java:335) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:601) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:368) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) ~[tomcat-embed-jasper-8.5.16.jar:8.5.16]
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.t246osslab.easybuggy4sb.core.filters.SecurityFilter.doFilter(SecurityFilter.java:69) ~[classes/:na]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.t246osslab.easybuggy4sb.core.filters.AuthenticationFilter.doFilter(AuthenticationFilter.java:75) ~[classes/:na]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.t246osslab.easybuggy4sb.core.filters.EncodingFilter.doFilterInternal(EncodingFilter.java:33) ~[classes/:na]
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
          at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16]
          at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
  </code></pre>
  
  <p>Does anyone know the solution or workaround?</p>
  
  <p><strong>Environment:</strong></p>
  
  <ul>
  <li>Spring Boot 1.5.6.RELEASE</li>
  </ul>
  
  <p>I don't need alternative solutions using Thymeleaf.</p>
  
  <hr>
  
  <p>EDIT:</p>
  
  <p><strong>Steps to reproduce:</strong></p>
  
  <ol>
  <li><code>git clone https://github.com/k-tamura/easybuggy4sb.git</code></li>
  <li><code>cd easybuggy4sb</code></li>
  <li><p>Add the following dependencies to pom.xml.</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
      &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
        &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jstl&lt;/artifactId&gt;
  &lt;/dependency&gt;
  </code></pre></li>
  <li><p>Add the following property to src/main/resources/application.properties (in order to avoid exceptions during startup):</p>
  
  <pre><code>server.tomcat.additional-tld-skip-patterns=*.jar
  </code></pre></li>
  <li><p>Add test.jsp file into src/main/webapp:</p>
  
  <pre><code>&lt;%@ page pageEncoding="UTF-8"%&gt;
  &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
  </code></pre></li>
  <li><code>mvn spring-boot:run</code></li>
  <li><p>Access to <a href="http://localhost:8080/test.jsp" rel="noreferrer">http://localhost:8080/test.jsp</a>
  -> The following exception occurs:</p>
  
  <pre><code>There was an unexpected error (type=Internal Server Error, status=500).
  The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application
  </code></pre></li>
  </ol>