¿Cómo instalar JSTL? Falla con "No se puede resolver el uri absoluto" o "No se puede encontrar taglib" o NoClassDefFoundError o ClassCastException

Resuelto lukastymo asked hace 13 años • 22 respuestas

No sé qué hice incorrectamente, pero no puedo incluir JSTL. Lo he hecho jstl-1.2.jar, pero desafortunadamente recibo una excepción:

org.apache.jasper.JasperException: la uri absoluta: http://java.sun.com/jstl/core no se puede resolver ni en web.xml ni en los archivos jar implementados con esta aplicación.

Tengo esto en pom.xml:

<dependency>
  <groupId>taglibs</groupId>
  <artifactId>standard</artifactId>
  <version>1.1.2</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>

Estoy intentando usarlo de la siguiente manera:

<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
lukastymo avatar Feb 08 '11 07:02 lukastymo
Aceptado

En su caso específico,

org.apache.jasper.JasperException: la uri absoluta: http://java.sun.com/jstl/core no se puede resolver ni en web.xml ni en los archivos jar implementados con esta aplicación.

ese URI es para JSTL 1.0, pero en realidad estás usando JSTL 1.2, que usa URI con una /jspruta adicional. Este cambio de URI se debe a que JSTL, que inventó las expresiones EL, se integró desde la versión 1.1 como parte de JSP 2.0 (¡lanzado en 2001!) para compartir/reutilizar la lógica EL también en JSP simple. Consulte también Diferencia entre JSP EL, JSF EL y Unified EL .

Por lo tanto, corrija el URI de taglib según la documentación de JSTL 1.2 :

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Además, debe asegurarse absolutamente de no incluir varios archivos JSTL JAR con versiones diferentes juntos en la ruta de clase del tiempo de ejecución o versiones que no coincidan con la versión esperada por el tiempo de ejecución de destino (el servidor) o simplemente con la API sin implicación. De lo contrario, corre el riesgo de ver otros errores como los siguientes:

org.apache.jasper.JasperException: no se puede encontrar el descriptor de la biblioteca de etiquetas para "http://java.sun.com/jsp/jstl/core"

org.apache.jasper.JasperException: no se puede encontrar taglib [c] para URI: [jakarta.tags.core]

java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/TagLibraryValidator

java.lang.NoClassDefFoundError: jakarta/servlet/jsp/tagext/TagLibraryValidator

java.lang.ClassCastException: la clase org.apache.taglibs.standard.tlv.JstlCoreTLV no se puede convertir a la clase jakarta.servlet.jsp.tagext.TagLibraryValidator

Este es un error bastante común entre los usuarios de Tomcat. El problema con Tomcat es que no ofrece JSTL listo para usar y, por lo tanto, debe instalarlo manualmente. Esto no es necesario en los servidores normales de Yakarta EE. Consulte también ¿Qué es exactamente Java EE? y ¿ Cómo configurar correctamente las bibliotecas Jakarta EE en Maven pom.xml para Tomcat?

En su caso específico, su pom.xml básicamente le dice que tiene jstl-1.2.jar y standard-1.1.2.jar juntos. Esto está mal. Básicamente estás mezclando JSTL 1.2 API+impl de Oracle (GlassFish) con JSTL 1.1 impl de Apache. Debe eliminar las implementaciones JSTL duplicadas y limitarse a una sola implementación JSTL y la versión de API debe coincidir con la versión impl y la versión de API debe ser compatible con el tiempo de ejecución de destino.

Instalación de JSTL en Tomcat 10.1.x

En caso de que ya esté en Tomcat 10.1.x (la segunda versión Jakartificada, con jakarta.*paquete en lugar de javax.*paquete, pero la primera versión con las jakarta.tags.* URN del espacio de nombres actualizadas en lugar de http://java.sun.com/jsp/jstl/*las URL del espacio de nombres), use JSTL 3.0 a través de estas dependencias usando el alcance predeterminado de Maven de compile(¡porque Tomcat no lo proporciona listo para usar!):

<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>3.0.1</version>
</dependency>

Tenga en cuenta que la dependencia de API se debe a que esta versión no se incluye transitivamente a través de la dependencia impl, por lo que debe declararla explícitamente.

Los usuarios que no son Maven pueden lograr lo mismo colocando los siguientes dos archivos físicos en la /WEB-INF/libcarpeta del proyecto de la aplicación web (¡ no coloques ningún archivo estándar*.jar ni ningún archivo .tld suelto allí! Elimínalos si es necesario).

  • jakarta.servlet.jsp.jstl-api-3.0.0.jar (esta es la API JSTL 3.0)
  • jakarta.servlet.jsp.jstl-3.0.1.jar (este es el impl JSTL 3.0.1 de EE4J)

Como se dijo, los URI del espacio de nombres se han cambiado para convertirse en URN en lugar de URL. El núcleo de JSTL está disponible desde la versión 3.0 de JSTL a través de un URI de espacio de nombres más fácil de recordar en formato URN:

<%@ taglib prefix="c" uri="jakarta.tags.core" %>

Consulte también la documentación de JSTL 3.0 .

En caso de que realmente desee utilizar la implementación JSTL de Apache en lugar de EE4J, debe saber que no tienen una versión 3.0 y mucho menos una 2.0. La última versión publicada actualmente de la implementación JSTL de Apache es 1.2.3 y ya no se mantiene activamente desde febrero de 2015 . La implementación JSTL de EE4J (anteriormente Oracle/Sun) es actualmente (julio de 2023) su única opción.

Instalación de JSTL en Tomcat 10.0.x

En caso de que esté en Tomcat 10.0.x (la primera versión Jakartificada, con jakarta.*paquete en lugar de javax.*paquete), use JSTL 2.0 a través de esta única dependencia usando el alcance predeterminado de Maven compile(¡porque Tomcat no lo proporciona de fábrica!):

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>2.0.0</version>
</dependency>

Tenga en cuenta que la dependencia de la API ya está incluida de forma transitiva a través de esta dependencia implícita, por lo que no es necesario declararla explícitamente.

Los usuarios que no son Maven pueden lograr lo mismo colocando los siguientes dos archivos físicos en la /WEB-INF/libcarpeta del proyecto de la aplicación web (¡ no coloques ningún archivo estándar*.jar ni ningún archivo .tld suelto allí! Elimínalos si es necesario).

  • jakarta.servlet.jsp.jstl-api-2.0.0.jar (esta es la API JSTL 2.0)
  • jakarta.servlet.jsp.jstl-2.0.0.jar (este es el impl JSTL 2.0 de EE4J)

Instalación de JSTL en Tomcat 9-

En caso de que aún no esté en Tomcat 10, pero aún tenga Tomcat 9 o anterior, use JSTL 1.2 a través de esta única dependencia (esto es compatible con Tomcat 9/8/7/6/5 pero no anterior) usando el alcance predeterminado de Maven. de compile(¡porque Tomcat no lo proporciona listo para usar!):

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>1.2.6</version>
</dependency>

Tenga en cuenta que la dependencia de la API ya está incluida de forma transitiva a través de esta dependencia implícita, por lo que no es necesario declararla explícitamente.

Los usuarios que no son Maven pueden lograr lo mismo colocando los siguientes dos archivos físicos en la /WEB-INF/libcarpeta del proyecto de la aplicación web (¡ no coloques ningún archivo estándar*.jar ni ningún archivo .tld suelto allí! Elimínalos si es necesario).

  • jakarta.servlet.jsp.jstl-api-1.2.7.jar (esta es la API JSTL 1.2)
  • jakarta.servlet.jsp.jstl-1.2.6.jar (este es el impl JSTL 1.2 de EE4J)

Instalación de JSTL en un servidor JEE normal

En caso de que esté utilizando un servidor Jakarta EE normal como WildFly, Payara, TomEE, GlassFish, WebSphere, OpenLiberty, WebLogic, etc. en lugar de un contenedor de servlet básico como Tomcat, Jetty, Undertow, etc., entonces no necesita instalar JSTL explícitamente. Los servidores normales de Yakarta EE ya proporcionan JSTL listo para usar. En otras palabras, no necesita agregar JSTL pom.xmlni soltar ningún archivo JAR/TLD en la aplicación web. Sólo la providedcoordenada EE de Yakarta con alcance es suficiente:

<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version><!-- 10.0.0, 9.1.0, 9.0.0, 8.0.0, etc depending on your server --></version>
    <scope>provided</scope>
</dependency>

Asegúrese de que la versión web.xml sea correcta

Además, también debe asegurarse de que su web.xmldeclaración se ajuste al menos a Servlet 2.4 y, por lo tanto, no a Servlet 2.3 o anterior. De lo contrario, las expresiones EL dentro de las etiquetas JSTL no funcionarían. Elija la versión más alta que coincida con su contenedor de destino y asegúrese de que no tenga ninguna <!DOCTYPE>en ningún lugar web.xml, ya que de lo contrario aún activaría el modo Servlet 2.3. Aquí hay un ejemplo compatible con Servlet 6.0 (Tomcat 10.1.x):

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns="https://jakarta.ee/xml/ns/jakartaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
    version="6.0">

    <!-- Config here. -->

</web-app>

Y aquí hay un ejemplo compatible con Servlet 5.0 (Tomcat 10.0.x):

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns="https://jakarta.ee/xml/ns/jakartaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
    version="5.0">

    <!-- Config here. -->

</web-app>

Y aquí hay un ejemplo compatible con Servlet 4.0 (Tomcat 9):

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    version="4.0">

    <!-- Config here. -->

</web-app>

Ver también:

  • Documentación de taglib principal de JSTL (para los URI de taglib correctos)
  • Expresiones EL no evaluadas en JSP
  • Cómo configurar pom.xml para Tomcat 10+ o Tomcat 9-
BalusC avatar Feb 08 '2011 00:02 BalusC

@BalusC tiene toda la razón, pero si aún encuentra esta excepción, significa que algo ha hecho mal. La información más importante que encontrará se encuentra en la página Información de etiqueta SO JSTL .

Básicamente, este es un resumen de lo que debe hacer para abordar esta excepción.

  1. Verifique la versión del servlet en web.xml:<web-app version="2.5">

  2. Compruebe si la versión JSTL es compatible con esta versión de servlet: la versión 2.5 del servlet usa JSTL 1.2 o la versión 2.4 del servlet usa JSTL 1.1

  3. Su contenedor de servlets debe tener la biblioteca adecuada o debe incluirla manualmente en su aplicación. Por ejemplo: JSTL 1.2 requiere jstl-1.2.jar

Qué hacer con Tomcat 5 o 6:

Debe incluir los archivos jar apropiados en su directorio WEB-INF/lib (funcionará solo para su aplicación) o en tomcat/lib (funcionará globalmente para todas las aplicaciones).

Lo último es un taglib en tus archivos jsp. Para JSTL 1.2, el correcto es este:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
lukastymo avatar Oct 05 '2011 20:10 lukastymo

Encontré otra razón para este tipo de error: en mi caso, alguien configuró la propiedad conf/catalina.propertiesde configuración para evitar mensajes de advertencia de registro, omitiendo así el análisis necesario de Tomcat. Cambiar esto nuevamente al valor predeterminado de Tomcat y agregar una lista apropiada de archivos jar para omitir (sin incluir jstl-1.2 o spring-webmvc) resolvió el problema.tomcat.util.scan.StandardJarScanFilter.jarsToSkip*

resnbl avatar Jan 09 '2016 06:01 resnbl
jstl-1.2.jar --> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
jstl-1.1.jar --> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

También verifique los archivos jar de dependencia que ha agregado javax.servlet.jaro javax.servlet.jsp.jstl-1.2.1.jarno en su carpeta WEB-INF/lib. En mi caso estos dos resolvieron el problema.

KKA avatar Jan 03 '2014 07:01 KKA

Agregue el jstl-1.2.jara la tomcat/libcarpeta.

Con esto, tu error de dependencia se solucionará nuevamente.

Hadi Rasouli avatar Jul 09 '2015 21:07 Hadi Rasouli