I have actually a similar problem as described here JAX-RS Resource not found in GlassFish Server. Since one should not ask for help in the answers I make a new question.
I created a project named "SPCore" which is a simple RESTful Webservice. It uses jax-rs libs, jdk 11 and a Tomcat 9.0.44 server. I have an index.html in the webapps folder which shows Hello World. The context path is set to /sp-core
. If I'm calling localhost:8080/sp-core
the index.html file is returned. So that works.
I have some resources (I will only show one as example). The resource "ProcessEventResource" should return "hello world" as plain text when a GET request comes. The path is set to @Path("processEvent")
. Sadly I get an error 404 when I'm calling localhost:8080/sp-core/processEvent
I tried so far:
add an / at the beginning of the path declaration
I added a subclass application as mentioned here in the updated answer JAX-RS Resource not found in GlassFish Server. Still I get the 404 error when calling localhost:8080/sp-core/api/rest/processEvent
I have the assumption that something with the servlets or paths is not working correctly.
In the following I will provide my project structure, the pom file, the resource and the application class. I cut some small parts (package names, group-id, ...) which refers to the company I'm working for. If you need more Information please let me know.
pom.xml:
<?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>
<artifactId>sp-core</artifactId>
<version>1.0-SNAPSHOT</version>
<name>sp-core</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
processEventResource which simply returns hello world:
@Path("processEvent")
@Provider
public class ProcessEventResource {
public ProcessEventResource(){
}
@GET
@Produces("text/plain")
public String processEvent() {
return "Hello, World!";
}
}
RestApplication class:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api/rest")
public class RestApplication extends Application {
}
I would expect to get the hello world response when I'm calling localhost:8080/sp-core/api/rest/processEvent
Thanks in advance for your help and time.
+++++++++++++++++++++++++++Update+++++++++++++++++++++++++++
I switched from dependency javax to jersey and added a web.xml file. The new pom.xml looks like this
<name>sp-core</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
The web.xml looks like this:
<display-name>sp-core</display-name>
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Now I either get a 404 with message "Not Found" or "The requested resource [/sp-core/api/rest/processEvent] is not available". Which path should go where so I get the return "Hello World" when I call localhost:8080/sp-core/api/rest/processEvent
+++++++++++++++++++++++++++Update+++++++++++++++++++++++++++
I added init parameter to the web.xml
<init-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>abc.de.fg.SPCore.RestApplication</param-value>
</init-param>
The error message is still the same.
After reading many stackoverflow questions, JAX-RS docu and in the end maven docu I finally got it done. So I will show what I have done in the end.
As I wrote in the first update I added a web.xml file which ended up looking like this.
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>sp-core</display-name>
<servlet>
<servlet-name>restServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>abc.de.fg.sp_core.RestApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>restServlet</servlet-name>
<url-pattern>/api/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Please note, that the param name for the application is javax.ws.rs.Application and not javax.ws.rs.core.Application as said in the documentation (always read the notes ...).
I ended up only using the jersey container-servlet and the jersey-hk2 dependencies (JSON dependency is only for another resource). So the pom.xml looks like the following:
<?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>abc.de.fg</groupId>
<artifactId>sp-core</artifactId>
<version>1.0-SNAPSHOT</version>
<name>sp-core</name>
<packaging>war</packaging>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
</project>
My RestApplication overrides the getClasses Method from the Application class. There I added all my resources. The ApplicationPath is set to /*
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
@ApplicationPath("/*")
public class RestApplication extends Application {
public RestApplication() {
}
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(ProcessEventResource.class);
return s;
}
}
And then it finally worked and I got my Hello World when requesting http://localhost:8080/sp-core/api/rest/processEvent
.
Another short problem I run into was a 500 error missing RestApplication class. Simply forgot to maven compile ...
Hope this question and answer helps others. Cheers :)