Skip to content
Advertisement

JSP / JSTL causes NoClassDefFound error for TagSupport

This problem has been driving me mad for several weeks now and I suspect that the resolution, once I find it, will be simple. I have looked at every relevant answer I can find in StackOverflow but haven’t managed to resolve it, so I am hopeful that someone will be able to help me.

I have re-created the problem in a very simple web app for simplicity so I hope this will make it easier for people to help.

Here is the (simplified) problem:

  • I have a Java EE web app which comprises a single JSP which uses the Core JSTL Tag Library.

  • I have downloaded the two JSTL jars which I believe are relevant. These are:

    javax.servlet.jsp.jstl-1.2.1.jar and javax.servlet.jsp.jstl-api-1.2.1.jar

  • I have placed these two files in my Tomcat lib folder.

  • In my simplified web app there is no app library (WEB-INF/lib) so I am pretty sure I haven’t duplicated the files anywhere else within the application.

  • I am referencing servlet 2.5 in web.xml.

When I run the app I get the following error (edited to include full stack trace):

java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagSupport
    java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:295)
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    java.lang.ClassLoader.loadClass(ClassLoader.java:295)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    java.security.AccessController.doPrivileged(Native Method)
    java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    java.lang.Class.forName0(Native Method)
    java.lang.Class.forName(Class.java:249)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1701)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    org.apache.jasper.compiler.Parser.parseCustomTag(Parser.java:1223)
    org.apache.jasper.compiler.Parser.parseElements(Parser.java:1452)
    org.apache.jasper.compiler.Parser.parse(Parser.java:138)
    org.apache.jasper.compiler.ParserController.doParse(ParserController.java:242)
    org.apache.jasper.compiler.ParserController.parse(ParserController.java:102)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:198)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Here is my jsp file, index.jsp

<%-- Created by IntelliJ IDEA. --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test JSP</title>
</head>
<body>
    <h1>
        Test Heading
    </h1>
    <c:if test="true">
        <p>True</p>
    </c:if>
</body>
</html>

Here is my web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">
    <servlet>
        <servlet-name>myjsp</servlet-name>
        <jsp-file>/index.jsp</jsp-file>
    </servlet>
    <servlet-mapping>
        <servlet-name>myjsp</servlet-name>
        <url-pattern>/myjsp</url-pattern>
    </servlet-mapping>
</web-app>

Finally, for what it is worth, here is a list of files within my Tomcat lib folder:

annotations-api.jar
catalina-ant.jar
catalina-ha.jar
catalina-tribes.jar
catalina.jar
ecj-4.2.2.jar
el-api.jar
jasper-el.jar
jasper.jar
javax.servlet.jsp.jstl-1.2.1.jar
javax.servlet.jsp.jstl-api-1.2.1.jar
jsp-api.jar
servlet-api.jar
tomcat-api.jar
tomcat-coyote.jar
tomcat-dbcp.jar
tomcat-i18n-es.jar
tomcat-i18n-fr.jar
tomcat-i18n-ja.jar
tomcat-jdbc.jar
tomcat-util.jar

NOTE:

In my original app I was using a version 3.0 web.xml but I am getting the same error using 2.5.

I have found that if I change the tag lib declaration within the jsp file from

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

to

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

I get exactly the same error, which surprises me. I would have thought I would get something like TLD file not found type error without the “/jsp” in the declaration, so I wonder whether that is a clue?

If I comment out the core tags (<c:if ...>) The jsp works and displays the text.

I hope there is enough information here for people to help. If you need any further clarification then let me know.

Advertisement

Answer

Firstly, thanks to everyone that tried to help with this. I have now resolved the error and the solution was not something I would have expected anyone to spot. I can’t accept your answers as they weren’t the correct solution but I can’t upscore them either as being helpful as I don’t have enough privileges – sorry about that!

The problem was this:

On a Mac, as part of the folder structure to support Java, there is a folder called

/Library/Java/Extensions

I am not absolutely sure what this folder is supposed to be used for but I had misinterpreted its purpose and had been using it to hold jar files which I would then pull in to my project through my IDE (IntelliJ IDEA).

The files I was downloading were actually libraries to be used within my web app by Tomcat (e.g. Tag Libraries). There were a whole load of files in there from various projects at various times and I was assuming that this wouldn’t be a problem as the folder was just a repository for me to store things and then pull in what I needed for my project.

I don’t pretend to understand exactly what is happening at a low level, but essentially, when I run my web app under Tomcat, Tomcat invokes the JVM in order to run and within the JVM, it includes the /Library/Java/Extensions folder in its class path.

As I understand it, Tomcat doesn’t use the Java classpath and has its own class loader functionality.

The upshot of this is that Tomcat was finding the correct versions of classes (such as jsp-api.jar) in my web app library, but when calling (non Tomcat) classes the JVM was finding some classes in the wrong place (i.e the …/Extensions folder) and they were incompatible, thus creating errors.

I know this is a bit vague – I have no intention of doing any more investigation to find out exactly what happened as I have spent weeks on this; the point is that when I removed all the jars from the …/Extensions folder and rebuilt my libraries from jars in another folder (I just used my downloads folder) everything eventually worked.

I don’t know what the lesson is there – I am amazed at how long this has taken and how much time I have wasted on what was (as is so often the case) a relatively simple problem.

If anyone happens to have a more technical grasp at what is happening under the covers and would care to add a comment that would be great.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement