Spring and Jetty ResourceServlet Issues
- Dominant language
- Java
- Stars
- 4.1k
- Forks
- 2k
- Avg merge
- 3d 56m
- Merged PRs (30d)
- 48
Description
**Jetty Version**
12.0.16
**Jetty Environment**
Spring Boot 3.4.3
Spring 6.2.3
Jakarta EE10
**Java Version**
17
**Question**
Recently, I've been working on upgrade from Java 8 to 17. This involved Jetty needing to be upgraded from 9 to 12. My primary focus is to get my app working in a standalone Jetty server.
Everything went smooth on the upgrade but I'm having issues with ResourceServlet. I understand we shouldn't be using DefaultServlet since it gives a warning in the logs to that effect.
This is what I thought would work but didn't.
```
@SpringBootApplication
public class App extends SpringBootServletInitializer
{
public static void main(String[] args) throws Exception
{
System.out.println("Starting DemoApplication...");
SpringApplication.run(App.class, args);
}
@Bean
public ServletRegistrationBean resourceServletRegistration()
{
ServletRegistrationBean registrationBean = new ServletRegistrationBean<>(new ResourceServlet(),
"/resources/*");
registrationBean.addInitParameter("resourceBase", "C:\\example\\resources");
registrationBean.addInitParameter("dirAllowed", "true");
return registrationBean;
}
}
```
When I tried to use this, I got ` org.eclipse.jetty.ee10.webapp.WebAppContext$Servlet
ApiContext is not org.eclipse.jetty.server.handler.ContextHandler$ScopedContext` error.
Github coPilot says the error is a mismatch between the Jetty server's context handling and the way the servlet is being registered and goes on to say it's a conflict between Jetty's ServletContextHandler and the Jakarta Servlet API's ServletContext. But I'm not sure if this is a correct assessment or what this could imply.
I kept trying to rewrite the code several times and found I could get it working by removing the `resourceServletRegistration` Bean and implementing onStartup as follows.
```
@Override
public void onStartup(ServletContext servletContext) throws ServletException
{
System.out.println("onStartup starting");
// Create a Jetty server and configure the context handler
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Retrieve the ServletHolder bean and map it to the desired URL pattern
ServletHolder resourceServletHolder = resourceServletHolder();
context.addServlet(resourceServletHolder, "/resources/*");
try
{
// Start the Jetty server
server.start();
}
catch (Exception e)
{
throw new ServletException("Failed to start Jetty server", e);
}
super.onStartup(servletContext);
}
```
However this does not work well with the rest of my annotated Beans in the class. I really don't want to create a new `Server` and assigning port and context path was not immediately available for me in my application properties.
What I want is to use the existing server context that is intializing/initialized and add this servlet resource to the existing servletContext. I kept hunting and I thought this would work for onStartup implementation.
```
@Override
public void onStartup(ServletContext servletContext) throws ServletException
{
System.out.println("onStartup starting");
super.onStartup(servletContext);
ServletRegistration.Dynamic resourceServlet = servletContext.addServlet("resourceServlet", ResourceServlet.class);
// Set initialization parameters
resourceServlet.setInitParameter("resourceBase", "C:\\example\\resources");
// Map the servlet to a URL pattern
resourceServlet.addMapping("/resources/*");
System.out.println("Servlet dynamically registered with Jakarta Servlet API.");
}
```
This did startup error-free but when I went to "localhost:8080/resources" to access a video file, I got nothing. No response in any jetty log. Web page just has ERR_CONNECTION_REFUSED. The servlet does not appear to be registered with the context at all.
What am I doing wrong here?
Contributor guide
Assessment
This issue has not been assessed yet.