28

I sometimes see these following declaration in pom.xml...

   <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    ....

as you can see, spring-boot-starter-web was declared as well as tomcat-embed-jasper.

isn't it spring-boot-starter-web already have an embedded tomcat? why some developers still declare tomcat-embed-jasper along with boot-starter-web? or is there any reason?

tuty_fruity
  • 523
  • 1
  • 5
  • 18

3 Answers3

28

As you said, the spring-boot-starter-web includes the spring-boot-starter-tomcat. You could check it here

The spring-boot-starter-tomcat includes the tomcat-embed-core. You could check it here

But, seems like tomcat-embed-core doesn't include tomcat-embed-jasper. In fact, is tomcat-embed-jasper who includes dependency with tomcat-embed-core. Check it here

Anyway, the tomcat-embed-jasper is marked as provided, so indicates that you expect the JDK or a container to provide the dependency at runtime. This scope is only available on the compilation and test classpath, and is not transitive.

In conclusion, the spring-boot-starter-web includes the tomcat embedded dependency but it doesn't includes the jasper embedded dependency, so that should be the reason to declare it separately.

Also, remember that using Spring IO Platform as parent you are able to manage dependencies easily. To know more about this you could read my post

Hope it helps,

Skillz
  • 308
  • 4
  • 10
jcgarcia
  • 3,762
  • 4
  • 18
  • 32
  • 18
    It might be worth adding that the reason why developers are adding `tomcat-embed-jasper` (in my understanding that was part of the question) usually will be that they want their embedded Tomcat to be able to compile jsp-files. Because that's what jasper does. `spring-boot-starter-web` does not include `tomcat-embed-jasper` so it has to be declared separately. That also explains the dependencies. The embedded Tomcat does not need jasper to work, you can still use servlets or other web filters. But of course jasper needs a container to compile jsp-files for. – Fencer Nov 16 '17 at 11:20
  • 1
    Thanks for the answer, but I followed the hierarchy mentioned by you, but for me "tomcat-embed-jasper" is not marked with "provided". Kindly help me to understand this. Thanks in advance. – Ashish Burnwal Feb 22 '18 at 10:24
  • 4
    Please note that Spring Boot recommends to avoid JSP as template engine, although it supports it. There are some known JSP limitations. Please check [Spring Boot Template Engines](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-template-engines) and [JSP Limitations](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-jsp-limitations). – Eder Luis Jorge Dec 30 '18 at 08:34
  • 1
    @AshishBurnwal By provided, he means it is marked as provided in the question itself. Not in the actual poms being referred in the links. – Manish Bansal Jan 16 '19 at 06:21
2

Extended from jcgarcia's answer.

Even it is provided, but when you build as war, spring-boot-maven-plugin will include two more jar : ecj-3.12.3.jar tomcat-embed-jasper-8.5.23.jar

Surasin Tancharoen
  • 5,520
  • 4
  • 32
  • 40
1

To those who are still facing this error in 2022 with Java Version 17, Maven Version 3.0.0 and Package Jar. I also ran into the same issue just now, seems like even though we set <scope>Provided</scope> Maven is not picking up the jar. What you can do instead is just take that completely off while adding the dependency and run the Maven to install dependencies again. It will fix it for sure. So your pom.xml file will go:-

From

 <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

To

 <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Jay K.C.
  • 11
  • 3