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:
The key points are:
- '
javax.servletis the correct group for the pre-Jakarta namespace' - '
javax.servlet-apiis the API artifact' - '
3.0.1is the common Servlet 3.0 API version' - '
providedmeans 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:
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:
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:
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
providedscope and packaging the servlet API into the application artifact unnecessarily. - Mixing
javax.servletimports 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
providedscope for normal container-based web applications. - Servlet 3.0 belongs to the
javax.servletnamespace, 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.

