简体   繁体   中英

Error compilling Jetty embeded application : org.eclipse.jetty.server reads package jakarta.servlet from both jetty.servlet.api and jakarta.servlet

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?

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...

  1. it lacks the proper module-info.class (this file is not present in the official dependency)
  2. it relies declaring the name jakarta.servlet as an automatic-module-name. (basically reserving the name for later upgrade to a proper module-info.class )
  3. exports every package in the jar and does not provide JPMS opens calls
  4. missing schemas needed for proper Jakarta Servlet Container execution

(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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM