How to Fix java.lang.AbstractMethodError in Tomcat (With Real Examples)

When starting a Java web application on Apache Tomcat, you might encounter an intimidating message like this:

SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.filterStart
Exception starting filter [monitoringFilter]
java.lang.AbstractMethodError

This type of error can prevent your application from starting altogether — but the good news is that it’s almost always caused by a simple library incompatibility.

Let’s explore what this error means, why it happens, and how to resolve it properly.


🧩 What Is java.lang.AbstractMethodError?

The java.lang.AbstractMethodError occurs when a class tries to call an abstract method that it doesn’t actually implement. In most cases, this happens due to version mismatches between compiled code and runtime libraries.

Example:

Imagine you compiled your project against version 1.2 of a library that defines an interface like this:

public interface MyFilter {
    void init(FilterConfig config);
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
}

Later, you upgraded the dependency on your server to version 1.3, where a new abstract method was added:

public interface MyFilter {
    void init(FilterConfig config);
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
    void destroy();  // newly added
}

Your old compiled filter class doesn’t implement destroy(), so at runtime, Tomcat throws:

java.lang.AbstractMethodError

⚙️ Common Scenarios That Trigger This Error

1️⃣ Outdated or Conflicting JAR Files

If your project has multiple versions of the same library (for example, servlet-api.jar in both Tomcat and WEB-INF/lib), one version might shadow another.

Example:

  • Tomcat already provides servlet-api.jar.
  • Your app’s WEB-INF/lib folder also contains a different servlet-api.jar.
  • During startup, Tomcat loads the wrong version, leading to AbstractMethodError.

Fix:
Remove servlet-api.jar (and similar container-provided libraries) from your WEB-INF/lib.
Let Tomcat use its own provided version.


2️⃣ Filter or Listener Compiled Against a Different Servlet Version

Suppose you have a MonitoringFilter implemented like this:

public class MonitoringFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) { /* ... */ }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(request, response);
    }

    // Missing destroy() method
}

When deployed on a newer Tomcat version that expects destroy() to exist, startup fails with AbstractMethodError.

Fix:
Always implement all methods required by the interface:

@Override
public void destroy() {
    // cleanup logic
}

3️⃣ Dependency Version Conflict in Maven or Gradle

If you use Maven or Gradle, dependency conflicts can be silent killers. For example, two dependencies might pull in different versions of the same library.

You can check for conflicts with:

mvn dependency:tree

or in Gradle:

gradle dependencies

Look for libraries like javax.servlet, jakarta.servlet, or spring-web appearing multiple times with different versions.

Fix:
Force the correct version in your build file.
For example, in Maven:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>
  </dependencies>
</dependencyManagement>

4️⃣ Mixing javax.* and jakarta.* Packages

With the transition from Java EE to Jakarta EE, the package names changed from javax.servlet.* to jakarta.servlet.*. Mixing them in the same project can cause runtime incompatibility.

Fix:
Make sure your dependencies and Tomcat version align:

  • Tomcat 9 or olderjavax.*
  • Tomcat 10 or newerjakarta.*

If you migrate from Tomcat 9 → 10, use the Eclipse Transformer Tool to automatically rename packages.


🔍 Step-by-Step Troubleshooting Guide

  1. Check Tomcat Version
    $CATALINA_HOME/bin/version.sh
    
  2. Inspect Your Classpath
    • Check /WEB-INF/lib for duplicates.
    • Remove libraries already provided by Tomcat.
  3. Review Dependencies
    • Run mvn dependency:tree or gradle dependencies.
    • Align all servlet-related versions.
  4. Clean and Rebuild
    mvn clean package
    

    or

    gradle clean build
    
  5. Check Interface Changes
    • Open your filter class (like MonitoringFilter) and make sure it implements all interface methods.
  6. Review web.xml
    • Ensure the filter class name is correct and refers to the right package.

    Example:

    <filter>
        <filter-name>monitoringFilter</filter-name>
        <filter-class>com.example.filters.MonitoringFilter</filter-class>
    </filter>
    

🧠 Example of a Clean Filter Implementation

Here’s a working example compatible with Tomcat 9+:

package com.example.filters;

import javax.servlet.*;
import java.io.IOException;

public class MonitoringFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MonitoringFilter initialized.");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);
        long end = System.currentTimeMillis();
        System.out.println("Request processed in " + (end - start) + " ms");
    }

    @Override
    public void destroy() {
        System.out.println("MonitoringFilter destroyed.");
    }
}

This version properly implements all required methods and avoids the AbstractMethodError.


🧰 Quick Recap

Root CauseTypical Fix
Old or duplicate JARsRemove duplicates and use Tomcat’s libraries
Missing method in interfaceRebuild code to include new interface methods
Dependency mismatchAlign versions in pom.xml or build.gradle
Migration to Jakarta EEUse consistent package naming

🏁 Conclusion

java.lang.AbstractMethodError may look scary, but it’s almost always caused by a version mismatch between what your code expects and what’s available at runtime.
By aligning dependencies, cleaning your classpath, and ensuring consistent library versions, you can fix the issue quickly and keep your Tomcat applications stable and reliable.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back