Issue
Just want to build a Java application with a REST API (JAX-RS implemented by Jersey 2.33) that runs in a standalone Servlet 5 container, e.g. Tomcat 10. For this the build process (via Maven) creates a *.war file which is put subsequently into the webapps/ folder to start it.
The problem is that the JAX-RS API, that is to say its servlet, is not coming up. So calling the URL
http://localhost:8080/weld/api/address
produces HTTP Status 404 (not found).
The pom.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.test</groupId>
<artifactId>weld</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>weld Maven Webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<servlet-api.version>5.0.0</servlet-api.version>
<jax-rs-api.version>2.1.6</jax-rs-api.version>
<jersey.version>2.33</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>${jax-rs-api.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
</dependencies>
<build>
<finalName>weld</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
The required dependencies and the rest to get it to work I have read from the Jersey documentation. The *.war doesn't contain any web.xml because since Servlet API 3.1 this is optional. The class javax.ws.rs.core.Application which should actually auto-detected and bootstrap the JAX-RS API looks as follows:
package de.test.weld;
import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("api")
public class MyApplication extends ResourceConfig {
public MyApplication() {
registerClasses(AddressService.class);
}
}
The Java class with the very endpoint looks then like this:
package de.test.weld;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/address")
public class AddressService {
@GET
@Produces(MediaType.APPLICATION_JSON)
public String getAddress() {
return "any text, bla, nonsense";
}
}
Anything essential seems to be missing so that the Jersey Sevlet can be started.
A glimpse into the *.war looks like this:
$> jar -tvf webapps/weld.war
0 Sat Mar 13 13:13:24 CET 2021 META-INF/
131 Sat Mar 13 13:13:22 CET 2021 META-INF/MANIFEST.MF
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/test/
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/test/weld/
0 Sat Mar 13 13:13:24 CET 2021 WEB-INF/lib/
619 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/test/weld/AddressService.class
1025 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/test/weld/TestServlet.class
581 Sat Mar 13 13:13:24 CET 2021 WEB-INF/classes/de/test/weld/MyApplication.class
25058 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jakarta.annotation-api-1.3.5.jar
19479 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/osgi-resource-locator-1.0.3.jar
1174508 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jersey-common-2.33.jar
942190 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jersey-server-2.33.jar
18140 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jakarta.inject-2.6.1.jar
253811 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jersey-client-2.33.jar
91930 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jakarta.validation-api-2.0.2.jar
32383 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jersey-container-servlet-2.33.jar
73402 Fri Mar 12 15:26:10 CET 2021 WEB-INF/lib/jersey-container-servlet-core-2.33.jar
140376 Fri Mar 12 15:11:24 CET 2021 WEB-INF/lib/jakarta.ws.rs-api-2.1.6.jar
0 Sat Mar 13 13:13:24 CET 2021 META-INF/maven/
0 Sat Mar 13 13:13:24 CET 2021 META-INF/maven/de.test/
0 Sat Mar 13 13:13:24 CET 2021 META-INF/maven/de.test/weld/
2757 Sat Mar 13 13:12:34 CET 2021 META-INF/maven/de.test/weld/pom.xml
106 Sat Mar 13 13:13:24 CET 2021 META-INF/maven/de.test/weld/pom.properties
Here are some information about the versions in use: Java 11, Maven 3.6, JAX-RS (Jersey 2.33), Servlet API 5.0.0, Tomcat 10 or Jetty 11
Solution
You need to use Jersey 3.x. The 3.x line is the first line that makes use of the Jakarta namespace. You have all the Jakarta dependencies (JAX-RS, Servlet), just the Jersey version you are using does not make use of them. See the Jersey docs for the latest 3.x version.
In the new Jakarta EE, all the javax
packaging has changed to jakarta
, e.g. jakarta.ws.rs.ApplicationPath
. Once you change the Jersey version (assuming you don't have any other old dependencies, you should get import errors. All the javax
imports should show errors. They should all be switched out with jakarta
. All the javax
imports (that includes JAX-RS, Servlet, Inject, etc).
Answered By - Paul Samsotha