Maven
Servlet 3.0
dependency management
Java
API integration

Maven dependency for Servlet 3.0 API?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If your project targets the Servlet 3.0 API, the Maven dependency is usually javax.servlet:javax.servlet-api:3.0.1 with provided scope. The important part is not only the artifact coordinates, but also understanding that the servlet container supplies the implementation at runtime.

The Standard Maven Dependency

For a traditional Servlet 3.0 application, the usual dependency looks like this:

xml
1<dependency>
2    <groupId>javax.servlet</groupId>
3    <artifactId>javax.servlet-api</artifactId>
4    <version>3.0.1</version>
5    <scope>provided</scope>
6</dependency>

The key points are:

  • 'javax.servlet is the correct group for the pre-Jakarta namespace'
  • 'javax.servlet-api is the API artifact'
  • '3.0.1 is the common Servlet 3.0 API version'
  • 'provided means the application server or servlet container supplies it'

That last point matters a lot. In a normal WAR deployment, Tomcat, Jetty, or another compatible container already includes the servlet implementation, so bundling it into your artifact is usually wrong.

Why provided Scope Is Important

Servlet applications are normally deployed into a runtime that already has the servlet classes. If you package your own copy into WEB-INF/lib, you can create classpath conflicts or unexpected behavior.

That is why provided is standard:

xml
<scope>provided</scope>

It keeps the dependency available at compile time without packaging it into the final deployable artifact.

If you are building an executable application that embeds a server directly, the setup is different. But the classic answer for a Servlet 3.0 web app deployed to a container is still provided.

Servlet 3.0 Features You Are Targeting

Servlet 3.0 introduced features that often explain why someone asks specifically for that API version:

  • annotation-based registration such as @WebServlet
  • asynchronous request processing
  • pluggability and easier component discovery
  • programmatic registration through ServletContext

A simple annotation-based servlet looks like this:

java
1import java.io.IOException;
2import javax.servlet.annotation.WebServlet;
3import javax.servlet.http.HttpServlet;
4import javax.servlet.http.HttpServletRequest;
5import javax.servlet.http.HttpServletResponse;
6
7@WebServlet("/hello")
8public class HelloServlet extends HttpServlet {
9    @Override
10    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
11        resp.setContentType("text/plain");
12        resp.getWriter().write("Hello, Servlet 3.0");
13    }
14}

This avoids the older web.xml mapping style for straightforward cases.

Do Not Mix Servlet 3.0 with Jakarta Coordinates

One common source of confusion is the Java EE versus Jakarta EE namespace change. Servlet 3.0 belongs to the older javax.servlet namespace, not jakarta.servlet.

If your code imports:

java
import javax.servlet.http.HttpServlet;

then the Maven dependency must come from the javax.servlet family. Using a Jakarta artifact with jakarta.servlet.* imports is a different platform generation and not a drop-in replacement for an old Servlet 3.0 project.

Container Compatibility Still Matters

The dependency in Maven does not force the runtime container to support Servlet 3.0. Your deployment target must support it too.

For example, if the code uses Servlet 3.0 annotations but is deployed to an older container that only supports an earlier servlet spec, the application can compile and still fail at deployment time.

That means version selection is really a contract between:

  • your source code
  • your Maven build
  • your target servlet container

All three must agree.

Common Pitfalls

  • Omitting provided scope and packaging the servlet API into the application artifact unnecessarily.
  • Mixing javax.servlet imports with Jakarta artifacts or vice versa.
  • Assuming the Maven dependency alone guarantees runtime container compatibility.
  • Using a newer servlet API artifact than the target container actually supports.
  • Forgetting that embedded-server applications may need a different setup than traditional WAR deployment.

Summary

  • The common Maven dependency for Servlet 3.0 is javax.servlet:javax.servlet-api:3.0.1.
  • Use provided scope for normal container-based web applications.
  • Servlet 3.0 belongs to the javax.servlet namespace, not Jakarta.
  • Make sure the target servlet container supports the same API level you compile against.
  • Treat the dependency, imports, and runtime container as one compatibility decision.

Course illustration
Course illustration

All Rights Reserved.