Reputation: 4487
I'm bulding an embeded Jetty application with Maven. jetty.version: 11.0.13 servlet-api.version: 5.0.0.
It is a multi module project.
One maven module, named "utils", depends on jakarta.servlet-api for compilling (scope is provided). The java module requires jakarta.servlet.
// utils' pom.xml
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
The maven "application" module adds the following dependencies and others.
// application's pom.xml
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
One of the other explicit dependency depends on the "utils" maven module.
The application's Java module contains:
requires utils;
requires org.eclipse.jetty.http;
requires org.eclipse.jetty.server;
requires org.eclipse.jetty.servlet;
When I compile the application, all dependency modules compile OK but I get this error when compilling the last module (the application) :
myapplication.BlaBla.java:[46,17] cannot access jakarta.servlet.http.HttpServlet class file for jakarta.servlet.http.HttpServlet not found
If I add the following dependency:
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
and add the following line to my application's module:
requires jakarta.servlet;
My editor warns:
Module 'application' reads package 'jakarta.servlet' from both 'jetty.servlet.api' and 'jakarta.servlet'
And the build obviously fails with many error messages like:
[ERROR] module org.eclipse.jetty.server reads package jakarta.servlet from both jetty.servlet.api and jakarta.servlet [ERROR] module org.eclipse.jetty.server reads package jakarta.servlet.http from both jetty.servlet.api and jakarta.servlet [ERROR] module org.eclipse.jetty.server reads package jakarta.servlet.descriptor from both jetty.servlet.api and jakarta.servlet [ERROR] module org.eclipse.jetty.server reads package jakarta.servlet.annotation from both jetty.servlet.api and jakarta.servlet [ ...
If I look at the jetty.servlet.api jar file, I see no package named jakarta.servlet.
I did notice that "jetty-jakarta-servlet-api-5.0.2.jar" contains the jakarta.servlet classes but I don't know to use this in my build process.
Help?
Upvotes: 2
Views: 1336
Reputation: 49462
Seems like you are trying to get JPMS working with Jetty 11.
The requires jakarta.servlet;
and the error about "module <blah> reads package <blah> from both <foo1> and <foo2>"
tell me this.
Here's what you need to know.
The standard artifact for Jakarta Servlet 5.0.0 from Maven Central is ...
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
</dependency>
This provides (in JPMS terms) the name jakarta.servlet
Look at the META-INF/MANIFEST.MF
in that file, you'll see the line
Automatic-Module-Name: jakarta.servlet
This dependency (unfortunately) isn't really well designed for JPMS due to ...
module-info.class
(this file is not present in the official dependency)jakarta.servlet
as an automatic-module-name. (basically reserving the name for later upgrade to a proper module-info.class
)(BTW, the upcoming Jakarta Servlet 6.0 has fixed this).
So why am I telling you this?
Jetty was an early adopter of JPMS, and had to address some of the faults of Jakarta Servlet 5.0.
One was the missing module-info.class
, another was the missing schemas (not present in the official Jakarta Servlet 5.0)
The replacement for jakarta.servlet
(the JPMS module name) version 5.0 when running a Jetty Server is ...
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-servlet-api</artifactId>
<version>5.0.2</version>
</dependency>
Use this when implementing a Jetty Server (like you are with your Embedded Jetty usage), and don't use the official dependency at all.
The Jetty Jakarta Servlet API 5.0.2 has a module-info.class
with the following declaration.
module jetty.servlet.api {
exports jakarta.servlet;
exports jakarta.servlet.annotation;
exports jakarta.servlet.descriptor;
exports jakarta.servlet.http;
exports jakarta.servlet.resources;
//open resources so Class.getResource() can access them
opens jakarta.servlet.resources;
}
In the future, when you upgrade to Jetty 12 (currently in alpha releases), you can use the official jakarta.servlet
dependency.
Upvotes: 4