javaspringspring-mvcjerseyspring-jersey

Spring 6 and Jersey 3 -> 404 Not Found


I am migrating from Spring 5 to Spring 6.0.13 and I am having problem with Jersey 3.1.1.

In WebInitializer :

public class WebInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        var webApplicationContext = new AnnotationConfigWebApplicationContext();
        webApplicationContext.register(this.createContextConfig());
        webApplicationContext.setServletContext(servletContext);
        servletContext.addListener(new ContextLoaderListener(webApplicationContext));

        var dispatcherServlet = new DispatcherServlet(webApplicationContext);
        ServletRegistration.Dynamic theDispatcherServlet  =
                servletContext.addServlet("dispatcherServlet", dispatcherServlet);
        theDispatcherServlet.setLoadOnStartup(1);
        theDispatcherServlet.addMapping("/*");

        ServletRegistration.Dynamic jerseyRegistration = servletContext.addServlet("jerseyServlet",
                "org.glassfish.jersey.servlet.ServletContainer");
        jerseyRegistration.setInitParameter("javax.ws.rs.Application", RestApplication.class.getName());
        jerseyRegistration.setInitParameter("jersey.config.server.provider.packages",
                JerseyGsonProvider.class.getPackageName());
        jerseyRegistration.setInitParameter("jersey.config.server.wadl.disableWadl", "true");
        jerseyRegistration.addMapping("/rest/*");
        jerseyRegistration.setLoadOnStartup(1);
   }

  ....
}

RestApplication:

@ApplicationPath("rest")
public class RestApplication extends ResourceConfig {

    public RestApplication() {
        registerClasses(FooResource.class);
        register(new LoggingFeature(Logger.global.getLogger("JerseyLogger"),
                Level.FINE, LoggingFeature.Verbosity.PAYLOAD_ANY, 8192));
        System.out.println("CLASSES REGISTERED IN JERSEY");//THIS MESSAGE IS NEVER PRINTED
    }
}

FooResource:

@Path("/foo")
public class FooResource {

    @GET
    @Produces(MediaType.TEXT_HTML)
    @Path("/temp")
    public String temp() {
        return "<body>Hello! This is temp rest</body>";
    }

}

And when I open http://127.0.0.1:8080/rest/foo/temp I get:

HTTP ERROR 404 Not Found
URI:    /rest/foo/temp
STATUS: 404
MESSAGE:    Not Found
SERVLET:    jerseyServlet
Powered by Jetty:// 12.0.3

Log:

jakarta.ws.rs.NotFoundException: HTTP 404 Not Found
    at jersey.server@3.1.1/org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:258) [jersey-server-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) [jersey-common-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) [jersey-common-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.internal.Errors.process(Errors.java:292) [jersey-common-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.internal.Errors.process(Errors.java:274) [jersey-common-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.internal.Errors.process(Errors.java:244) [jersey-common-3.1.1.jar:?]
    at jersey.common@3.1.1/org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) [jersey-common-3.1.1.jar:?]
    at jersey.server@3.1.1/org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:240) [jersey-server-3.1.1.jar:?]
    at jersey.server@3.1.1/org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:697) [jersey-server-3.1.1.jar:?]
    at jersey.container.servlet.core@3.1.1/org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) [jersey-container-servlet-core-3.1.1.jar:?]
    at jersey.container.servlet.core@3.1.1/org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) [jersey-container-servlet-core-3.1.1.jar:?]
    at jersey.container.servlet.core@3.1.1/org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:357) [jersey-container-servlet-core-3.1.1.jar:?]
    at jersey.container.servlet.core@3.1.1/org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311) [jersey-container-servlet-core-3.1.1.jar:?]
    at jersey.container.servlet.core@3.1.1/org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) [jersey-container-servlet-core-3.1.1.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1370) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:736) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1609) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.websocket.servlet@12.0.3/org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:195) [jetty-ee10-websocket-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1581) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1542) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:886) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:491) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:463) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.security@12.0.3/org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:571) [jetty-security-12.0.3.jar:?]
    at org.eclipse.jetty.ee10.servlet@12.0.3/org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:693) [jetty-ee10-servlet-12.0.3.jar:?]
    at org.eclipse.jetty.server@12.0.3/org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:809) [jetty-server-12.0.3.jar:?]
    at org.eclipse.jetty.server@12.0.3/org.eclipse.jetty.server.Server.handle(Server.java:179) [jetty-server-12.0.3.jar:?]
    at org.eclipse.jetty.server@12.0.3/org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:649) [jetty-server-12.0.3.jar:?]
    at org.eclipse.jetty.server@12.0.3/org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:471) [jetty-server-12.0.3.jar:?]
    at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322) [jetty-io-12.0.3.jar:?]
    at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) [jetty-io-12.0.3.jar:?]
    at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) [jetty-io-12.0.3.jar:?]
    at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:971) [jetty-util-12.0.3.jar:?]
    at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1196) [jetty-util-12.0.3.jar:?]
    at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1151) [jetty-util-12.0.3.jar:?]
    at java.base/java.lang.Thread.run(Thread.java:833) [?:?]

Could anyone say how to fix it?


Solution

  • Spring 6 is JakartaEE based (and not JavaEE) based. As the application does start without warning/error about non found classes/incompatible classes I assume the version of Jersey used is compatible with JakartaEE.

    However your configuration still reflects the old JavaEE configuration.

    jerseyRegistration.setInitParameter("javax.ws.rs.Application", RestApplication.class.getName());
    

    Should be

    jerseyRegistration.setInitParameter("jakarta.ws.rs.Application", RestApplication.class.getName());
    

    That should get you started. You also might want to checkout the Jersey Migration Guide which mentions this briefly as well as other things that have changed and might impact you.