I am trying to create a web app that complies with the Jakarta RESTful Web Services (formerly JAX-RS) specification, running on a WildFly server.
I can start a deployment and access the WildFly homepage. But when I want to access my resources (e.g. @Path("/health")
). I receive a FORBIDDEN
error:
When I looked at the management console I saw that there is no JAX_RS
deployedL
I am utterly lost at what to do. Can somebody help?
I have tried adding management and application users, creating a web.xml
, creating a extension of Application, creating a CORS filter, updating my pom.xml
file.
Insert api
into your URL. (Or whatever value is specified in your @ApplicationPath
annotation.)
http://localhost:8080/your_final_artifact_name_here/your_ApplicationPath_here/your_Path_here
The parts in that URL:
http://
https
).localhost:8080
your_final_artifact_name_here
-1.0-SNAPSHOT
, to produce a file artifact name. This value here is the formal name of your web app, your “context” in Jakarta Servlet lingo.your_ApplicationPath_here
@AppliationPath
annotation. For example, api
per the Maven template used by IntelliJ new-project wizard.your_Path_here
Path
annotation, the name of your REST resource.Your @Path
annotation is only part of the URL needed to access your REST resource. Before that in the URL is the text you specified in your @ApplicationPath
annotation on the class that extends Application
.
The catch is that part of the URL to the REST resource being accessed defined in the "@ApplicationPathof the class extending
Application`.
package work.basil.example.exjakartarestserver;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath ( "/api" )
public class HelloApplication extends Application { }
Notice the /api
in that code above. That must appear in your URL.
Here is our REST resource:
package work.basil.example.exjakartarestserver;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
@Path ( "/hello-world" )
public class HelloResource
{
@GET
@Produces ( "text/plain" )
public String hello ( )
{
return "Hello, World!";
}
}
Suppose, as in my case, that:
ExJakartaRestServer
.target
folder is ExJakartaRestServer-1.0-SNAPSHOT
.@ApplicationPath
value is /api
.@Path
value is /hello-world
as seen above. This is the name of your “REST resource”.Then, you can access your REST resource with this URL:
http://localhost:8080/ExJakartaRestServer-1.0-SNAPSHOT/api/hello-world
By the way, the code above was aimed at the Jakarta EE 11 generation of Jakarta RESTful Web Services, Eclipse Jersey, and WildFly.
May not matter, but if curious, here is my POM.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>work.basil.example</groupId>
<artifactId>ExJakartaRestServer</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ExJakartaRestServer</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>22</maven.compiler.release>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/jakarta.ws.rs/jakarta.ws.rs-api -->
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
</plugin>
</plugins>
</build>
</project>
scope
of library for Jakarta RESTful Web Services APINotice the scope
element on the dependency for the interfaces of jakarta.ws.rs-api
. That scope is provided
because we only need a copy of the interfaces while compiling, but we do not want to include them in our final software artifact (our WAR file). Those interfaces will be provided at runtime by the Jakarta EE compliant server on which we deploy (Wildfly in this case here). Jakarta EE compliant server such as Wildfly brings both the API (interfaces) and an implementation of Jakarta RESTful Web Services if that server supports either the Web profile or the “Full” profile of the Jakarta EE specification. Problems might ensue if we brought an additional unneeded copy of the interfaces along in our WAR.