I created a simple Maven web project in Eclipse Version 2021-03 deployed to Tomcat 9 with the following pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gillopez.web.jstl</groupId>
<artifactId>jstl-webapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>8.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>jstl-webapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
</plugins>
</build>
</project>
I created a simple JSP that includes a taglib directive for the core JSTL tag:
<%@page import="java.time.LocalDateTime"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<body>
<c:set var="stuff" value="<%= LocalDateTime.now() %>" />
Time on server is ${stuff}
</body>
</html>
However, I see the following error message in the JSP editor:
Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core"
If I run it on the server, I get this error: "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"
The JSTL packages are included in jakarta.jakartaee-web-api-8.0.0.jar:
Why am I getting this error message?
I can get it working by adding the following dependency in my pom.xml.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
Why do I need to do this if the JSTL packages are already included in the jakarta.jakartaee-web-api jar file?
The artifact jakarta.jakartaee-web-api
contains just the API jars of Jakarta EE 8, not the implementations. Since you used the provided
scope, you assume that the container will provide the implementations.
However Tomcat is not a full Jakarta EE 8 server (such as WildFly) and it implements only five specifications (cf. documentation): Servlet, JSP, EL, WebSocket and JASPIC. Therefore, for Tomcat 9, you should replace jakarta.jakartaee-web-api
with:
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>2.3.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>3.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>1.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.security.auth.message</groupId>
<artifactId>jakarta.security.auth.message-api</artifactId>
<version>1.1.3</version>
<scope>provided</scope>
</dependency>
All other APIs you want to use must be provided by your application together with their implementation.