0

I'm trying to run a web app which invokes a method which uses javax.servlet.http.HttpServletRequest. The web-app is written in Spring and runs on Tomcat 7.0.

I'm getting a ClassNotFoundException:

    SEVERE: Servlet.service() for servlet [crunchify] in context with path [] threw exception [Servlet execution threw an exception] with root cause
java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at io.demo.HttpServletRequestWrapper.getHeaders(HttpServletRequestWrapper.java:21)
    at io.demo.MagicHelper.doMagic(MagicHelper.java:25)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

This issue is resolved only if I edit Catalina.bat to include the servlet-api.jar. The problem is that as far as I understand from Tomcat's documentation, that is that the servlet-api.jar should be on the classpath.

Am I missing something??

I'll appreciate your help!

EDIT: This is my pom.

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>CrunchifySpringMVCTutorial</groupId>
    <artifactId>CrunchifySpringMVCTutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>

        <!-- <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> 
            <version>1.2</version> </dependency> -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>tomcat-maven-plugin</artifactId>
                <version>1.1</version>
                <configuration>
                    <url>http://localhost:8080/manager/text</url>
                    <server>TomcatServer</server>
                    <path>/SpringHelloWorld</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
nadavy
  • 1,755
  • 1
  • 18
  • 33

1 Answers1

-2

Tomcat probably does include this jar, but your IDE and standard JRE does not. So usually I always download J2EE related jars and include them into my app classpath, so I can compile and debug them in my IDE. Once those jars are part of my app everything is working just fine. The dependency usually defined in pom.xml file if you work with maven:

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • My issue is not a compilation issue. The issue I'm experiencing is at runtime. I'll edit the post and add my pom configuration. – nadavy Feb 21 '16 at 16:48
  • version 3.0.1 is a very old version for javax.servlet-api - one of the oldest available. try use 3.1.0 – Michael Gantman Feb 21 '16 at 17:05
  • Terrible advice. Look closer at stack trace for clue. It's Spring who can't find it, not Tomcat. If Tomcat couldn't find it, it would never be able to successfully hit and go beyond `HttpServlet.service` method which has exactly this dependency. As to referencing Java EE API related libraries in Maven, here's related food for read: http://stackoverflow.com/q/8081234 – BalusC Feb 21 '16 at 17:39
  • You are right about tomcat, but if it is Spring that can not find it (which it is) then adding it as dependency to application would resolve this problem. So you just flagged me fo no reason – Michael Gantman Feb 21 '16 at 17:44
  • @BalusC I'm actually instrumenting Spring. That's why the stack trace shows it, My code runs as a javaagent. – nadavy Feb 21 '16 at 18:21
  • @MichaelGantman I'm actually instrumenting Spring. That's why the stack trace shows it, My code runs as a javaagent. – nadavy Feb 21 '16 at 18:22
  • Target runtime provided dependencies are **in no way** supposed to be provided by webapp. It's recipe for classpath conflicts and portability disaster. – BalusC Feb 21 '16 at 18:24
  • @BalusC - what do you suggest to do? I'm a c# developer so I'm still trying to figure it out. Basically as far as I understand, by using provided I'm letting the end-user to determine which API to use (assuming of course that the method signature is the same). – nadavy Feb 21 '16 at 18:32