java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getParts()

Learn java.lang.nosuchmethoderror: javax.servlet.http.httpservletrequest.getparts() with practical examples, diagrams, and best practices. Covers java, spring, maven development techniques with vis...

Resolving java.lang.NoSuchMethodError: HttpServletRequest.getParts()

Hero image for java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getParts()

Understand and fix the common NoSuchMethodError when using HttpServletRequest.getParts() in Java web applications, often related to Servlet API versions.

The java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getParts() is a frequently encountered runtime exception in Java web applications, particularly when dealing with file uploads or multipart form data. This error indicates that the Java Virtual Machine (JVM) cannot find the getParts() method within the HttpServletRequest class at runtime, even though your code might compile successfully. This usually points to a mismatch between the Servlet API version used during compilation and the one available at runtime in your application server or classpath.

Understanding the Root Cause: Servlet API Version Mismatch

The getParts() method was introduced in the Servlet 3.0 API specification. If your application is compiled against Servlet API 3.0 or newer, but deployed on a server or environment that provides an older Servlet API (e.g., Servlet 2.5), this error will occur. The compiler sees the method, but the runtime environment does not have it. This is a classic example of a classpath issue where different versions of a library are present or expected.

flowchart TD
    A[Application Code] --> B{"Calls getParts()"}
    B --> C{Compile Time}
    C --> D["Servlet API 3.0+ (e.g., Maven/Gradle dependency)"]
    D -- Method Found --> E[Successful Compilation]
    E --> F{Runtime Deployment}
    F --> G["Application Server / Runtime Classpath"]
    G -- "Provides Servlet API 2.5 (or older)" --> H["java.lang.NoSuchMethodError: getParts()"]
    H -- "Method Not Found" --> I[Application Crash]

Flowchart illustrating the cause of NoSuchMethodError for getParts()

Common Scenarios and Solutions

This error typically arises in a few common scenarios, each with its own set of solutions. Identifying your specific situation is key to applying the correct fix.

Solution 1: Upgrade Your Application Server

The most straightforward solution is to ensure your application server supports Servlet API 3.0 or higher. For example:

  • Tomcat: Tomcat 7.x and newer support Servlet 3.0+. Tomcat 6.x supports Servlet 2.5.
  • Jetty: Jetty 8.x and newer support Servlet 3.0+.
  • WildFly/JBoss AS: WildFly 8+ (formerly JBoss AS 7+) supports Servlet 3.0+.

If upgrading the server is an option, it's often the cleanest fix as it aligns the runtime environment with your application's expectations.

Solution 2: Adjust Maven/Gradle Dependencies

If you cannot upgrade your server, you need to ensure your project's build configuration correctly handles the Servlet API dependency. The goal is to compile against the correct version and prevent the dependency from being bundled with your WAR/JAR if the server already provides it.

Maven

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version> <!-- Or 3.0.1, 4.0.1, etc. matching your server -->
    <scope>provided</scope>
</dependency>

Gradle

compileOnly 'javax.servlet:javax.servlet-api:3.1.0' // Or 3.0.1, 4.0.1, etc. matching your server

The key here is the <scope>provided</scope> in Maven or compileOnly in Gradle. This tells the build tool that the dependency is required for compilation but will be provided by the runtime environment (your application server) and should not be included in the final WAR/JAR file. If you accidentally include an older servlet-api.jar in your WEB-INF/lib directory, it can conflict with the server's provided API, leading to this error.

Solution 3: Check for Transitive Dependencies

Sometimes, the problematic Servlet API dependency might be pulled in transitively by another library. You can use your build tool's dependency tree analysis to identify these conflicts.

mvn dependency:tree

Command to view Maven dependency tree

gradle dependencies

Command to view Gradle dependency tree

Look for multiple versions of javax.servlet:servlet-api or javax.servlet:javax.servlet-api. If you find an older version being pulled in, you might need to exclude it or explicitly define a newer version to force resolution.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.20</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Example of excluding a transitive dependency in Maven

Solution 4: Verify web.xml Configuration

Ensure your web.xml (if used) declares the correct Servlet specification version. For Servlet 3.0+, it should look something like this:

<?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_3_1.xsd"
         version="3.1">
    <!-- Your servlet configurations -->
</web-app>

web.xml configuration for Servlet 3.1

If you're using an older web.xml (e.g., version 2.5), it explicitly tells the server to treat your application as a Servlet 2.5 application, which will not recognize getParts().

Practical Steps to Debug and Resolve

Follow these steps to systematically debug and resolve the NoSuchMethodError.

1. Identify Servlet API Version

Determine the Servlet API version supported by your application server (e.g., Tomcat 7 supports Servlet 3.0, Tomcat 8 supports Servlet 3.1, Tomcat 9/10 support Servlet 4.0/5.0+).

2. Check Project Dependencies

Review your pom.xml (Maven) or build.gradle (Gradle) for javax.servlet-api or servlet-api dependencies. Ensure the version matches your server's supported API and that the scope is provided (Maven) or compileOnly (Gradle).

3. Analyze Dependency Tree

Run mvn dependency:tree or gradle dependencies to check for any transitive dependencies pulling in an older Servlet API. Exclude them if necessary.

4. Inspect WAR/JAR Contents

Unzip your deployed WAR file and check the WEB-INF/lib directory. Ensure no servlet-api.jar or javax.servlet-api-*.jar is present. If it is, your provided or compileOnly scope is not working correctly, or a transitive dependency is bundling it.

5. Verify web.xml (if used)

Confirm that your web.xml declares the correct Servlet specification version (e.g., version="3.1" for Servlet 3.1).

6. Clean and Rebuild

Perform a clean build of your project (mvn clean install or gradle clean build) and redeploy the application to ensure all old artifacts are removed and new ones are correctly generated.