解决JSTL报错 java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
前言
前几篇笔记用到了一个JSTL3.0依赖
Springboot 3.x 项目使用 JSP 笔记
关于2023年如何开发一个Java JSP JSTL项目指南
有小伙伴照着我的笔记运行后会出现奇怪的报错
后来我自己的项目也跟着跑偏了哈哈哈
于是就有了这篇笔记
折腾
期初我写了2篇笔记,用的 jstl3.0
都是这段依赖
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.0</version>
</dependency>
这段maven依赖,本来是好好的,25号以后忽然间就不行了,报这个错Could not find artifact jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:jar:3.0.0-RC1 in nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public)
大概意思就是,阿里云里没有找到这个依赖,中央仓库里 mvnrepository
我也搜了确实没有 3.0.0-RC1
只有 3.0.0
查看他的pom
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>project</artifactId>
<groupId>org.eclipse.ee4j</groupId>
<version>1.0.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<name>Jakarta Standard Tag Library Implementation</name>
<version>3.0.0</version>
<description>Jakarta Standard Tag Library Implementation</description>
<url>https://projects.eclipse.org/projects/ee4j.jstl</url>
<issueManagement>
<system>github</system>
<url>https://github.com/eclipse-ee4j/jstl-api/issues</url>
</issueManagement>
<mailingLists>
<mailingList>
<name>JSTL dev mailing list</name>
<subscribe>https://dev.eclipse.org/mailman/listinfo/jstl-dev</subscribe>
<unsubscribe>https://dev.eclipse.org/mailman/listinfo/jstl-dev</unsubscribe>
<post>jstl-dev@eclipse.org</post>
<archive>https://dev.eclipse.org/mhonarc/lists/jstl-dev</archive>
</mailingList>
</mailingLists>
<developers>
<developer>
<id>yaminikb</id>
<name>Yamini K B</name>
<organization>Oracle Corporation</organization>
<organizationUrl>http://www.oracle.com/</organizationUrl>
</developer>
</developers>
<contributors>
<contributor>
<name>Kin Man Chung</name>
</contributor>
</contributors>
<licenses>
<license>
<name>EPL 2.0</name>
<url>http://www.eclipse.org/legal/epl-2.0</url>
<distribution>repo</distribution>
</license>
<license>
<name>GPL2 w/ CPE</name>
<url>https://www.gnu.org/software/classpath/license.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/eclipse-ee4j/jstl-api.git</connection>
<developerConnection>scm:git:ssh://git@github.com/eclipse-ee4j/jstl-api.git</developerConnection>
<url>https://github.com/eclipse-ee4j/jstl-api</url>
</scm>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<targetPath>META-INF</targetPath>
<directory>${project.basedir}/..</directory>
<includes>
<include>LICENSE.md</include>
<include>NOTICE.md</include>
</includes>
</resource>
<resource>
<targetPath>META-INF</targetPath>
<directory>${project.basedir}</directory>
<includes>
<include>LICENSE.md</include>
<include>NOTICE.md</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>enforce-maven</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.6.0</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgument>-Xlint:unchecked</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.3</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-SymbolicName>org.glassfish.web.jakarta.servlet.jsp.jstl</Bundle-SymbolicName>
<Export-Package>org.apache.taglibs.standard,
org.apache.taglibs.standard.extra.spath,
org.apache.taglibs.standard.functions,
org.apache.taglibs.standard.lang.jstl,
org.apache.taglibs.standard.lang.jstl.parser,
org.apache.taglibs.standard.lang.support,
org.apache.taglibs.standard.resources,
org.apache.taglibs.standard.tag.common.core,
org.apache.taglibs.standard.tag.common.fmt,
org.apache.taglibs.standard.tag.common.sql,
org.apache.taglibs.standard.tag.common.xml,
org.apache.taglibs.standard.tag.el.core,
org.apache.taglibs.standard.tag.el.fmt,
org.apache.taglibs.standard.tag.el.sql,
org.apache.taglibs.standard.tag.el.xml,
org.apache.taglibs.standard.tag.rt.core,
org.apache.taglibs.standard.tag.rt.fmt,
org.apache.taglibs.standard.tag.rt.sql,
org.apache.taglibs.standard.tag.rt.xml,
org.apache.taglibs.standard.tei,
org.apache.taglibs.standard.tlv,
org.glassfish.jstl.integration</Export-Package>
<Import-Package>!org.apache.xpath,
!org.apache.xpath.objects,
!org.apache.xpath.jaxp,
!org.apache.xml,
!org.apache.xml.dtm,
!org.apache.xml.utils,
!org.apache.xalan,
!org.apache.xalan.res,
!org.apache.xpath.res,
!org.apache.regexp,
!org.apache.bcel,
!java_cup.runtime,
!trax,
org.xml.sax.ext,
*</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
<manifestEntries>
<Extension-Name>jakarta.servlet.jsp.jstl</Extension-Name>
<Specification-Version>2.0</Specification-Version>
<Specification-Vendor>${project.organization.name}</Specification-Vendor>
<Implementation-Version>${project.version}</Implementation-Version>
<Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
<artifactSet>
<includes>
<include>xalan:xalan</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>xalan:xalan</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.apache.xpath</pattern>
<shadedPattern>org.eclipse.tags.shaded.org.apache.xpath</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.xml</pattern>
<shadedPattern>org.eclipse.tags.shaded.org.apache.xml</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.xalan</pattern>
<shadedPattern>org.eclipse.tags.shaded.org.apache.xalan</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.regexp</pattern>
<shadedPattern>org.eclipse.tags.shaded.org.apache.regexp</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.bcel</pattern>
<shadedPattern>org.eclipse.tags.shaded.org.apache.bcel</shadedPattern>
</relocation>
<relocation>
<pattern>java_cup.runtime</pattern>
<shadedPattern>org.eclipse.tags.shaded.java_cup.runtime</shadedPattern>
</relocation>
<relocation>
<pattern>trax</pattern>
<shadedPattern>org.eclipse.tags.shaded.trax</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
<configuration>
<includePom>true</includePom>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>timestamp-property</id>
<phase>validate</phase>
<goals>
<goal>timestamp-property</goal>
</goals>
<configuration>
<name>current.year</name>
<pattern>yyyy</pattern>
<locale>en_US</locale>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<groups>
<group>
<title>Jakarta Standard Tag Library Documentation</title>
<packages>org.apache.taglibs</packages>
</group>
</groups>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
<configuration>
<source>11</source>
<additionalJOption>-Xdoclint:none</additionalJOption>
<quiet>true</quiet>
<bottom>Copyright © 2019, ${current.year} Eclipse Foundation. All rights reserved.</bottom>
<docfilessubdirs>true</docfilessubdirs>
<groups>
<group>
<title>Jakarta Standard Tag Library Documentation</title>
<packages>jakarta.servlet.jsp.jstl*</packages>
</group>
</groups>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>tlddocs</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>generateTldDoc</id>
<phase>prepare-package</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includePluginDependencies>true</includePluginDependencies>
<includeProjectDependencies>false</includeProjectDependencies>
<mainClass>com.sun.tlddoc.TLDDoc</mainClass>
<arguments>
<argument>-doctitle</argument>
<argument>Jakarta Tags doc</argument>
<argument>-windowtitle</argument>
<argument>Jakarta Tags Doc</argument>
<argument>-d</argument>
<argument>${project.build.directory}/tlddoc</argument>
<argument>${project.basedir}/src/main/resources/META-INF/sql.tld</argument>
<argument>${project.basedir}/src/main/resources/META-INF/x.tld</argument>
<argument>${project.basedir}/src/main/resources/META-INF/fmt.tld</argument>
<argument>${project.basedir}/src/main/resources/META-INF/c.tld</argument>
<argument>${project.basedir}/src/main/resources/META-INF/fn.tld</argument>
</arguments>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>tagsdoc</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0-RC1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
确实存在一个 3.0.0-RC1
这里可以猜测出大概的结论:他以前一直依赖着3.0.0-RC1,然后忽然3.0.0-RC1有问题被Maven中央仓库删了
故事还没完
如果版本号改成 3.0.1
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>
就可以正常加载出依赖
表面看起来没有报错
但是有个巨坑等着我
JSP里一旦用了JSTL代码
例如 index.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<c:if test="true">
6
</c:if>
</body>
</html>
就会出现这个巨坑的报错
全网查了2天也没找到是什么问题
完整报错如下
HTTP状态 500 - 内部服务器错误
类型 异常报告
消息 org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
描述 服务器遇到一个意外的情况,阻止它完成请求。
例外情况
org.apache.jasper.JasperException: org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:578)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:422)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
根本原因。
org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:194)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
根本原因。
java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:129)
org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:58)
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:189)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:380)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:328)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
):注意 主要问题的全部 stack 信息可以在 server logs 里查看
最终的解决方案
maven依赖做如下修改
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
<!-- 排除这段可能出错的依赖 -->
<exclusions>
<exclusion>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 手动补上这段依赖 并指定一个安全的版本号 -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
也就是用 3.0.1
最新版,然后手动移除依赖中的依赖,再手动加载这个依赖中的依赖,用一个安全的版本号!
大功告成!