Hi,

we got this error after migrating our jetty spring boot boot app to spring boot 3.2.0. Any idea about how to fix it?

Could be related to these changes: https://github.com/spring-projects/spring-boot/issues/36135#issue-1782304102

or did I miss something? Same behavior with temurin jdk 17.0.9 and 21.0.1

org.springframework.context.ApplicationContextException: Unable to start web server
 |    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165)
 |    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:610)
 |    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
 |    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
 |    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
 |    at org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
 |    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1342)
 |    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1331)
 |    at com.example.Application.main(Application.java:10)
 | Caused by: java.util.ServiceConfigurationError: java.nio.file.spi.FileSystemProvider: Provider org.springframework.boot.loader.nio.file.NestedFileSystemProvider not found
 |    at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:593)
 |    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1219)
 |    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
 |    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
 |    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
 |    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
 |    at java.base/java.nio.file.spi.FileSystemProvider.loadInstalledProviders(FileSystemProvider.java:156)
 |    at java.base/java.nio.file.spi.FileSystemProvider$1.run(FileSystemProvider.java:207)
 |    at java.base/java.nio.file.spi.FileSystemProvider$1.run(FileSystemProvider.java:204)
 |    at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
 |    at java.base/java.nio.file.spi.FileSystemProvider.installedProviders(FileSystemProvider.java:204)
 |    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:336)
 |    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:288)
 |    at org.eclipse.jetty.util.resource.FileSystemPool.mount(FileSystemPool.java:115)
 |    at org.eclipse.jetty.util.resource.ResourceFactoryInternals$CompositeResourceFactory.mountIfNeeded(ResourceFactoryInternals.java:240)
 |    at org.eclipse.jetty.util.resource.ResourceFactoryInternals$CompositeResourceFactory.newResource(ResourceFactoryInternals.java:210)
 |    at org.eclipse.jetty.util.resource.ResourceFactoryInternals$LifeCycle.newResource(ResourceFactoryInternals.java:156)
 |    at org.eclipse.jetty.util.resource.ResourceFactory.newResource(ResourceFactory.java:320)
 |    at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.createResource(JettyServletWebServerFactory.java:348)
 |    at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.configureDocumentRoot(JettyServletWebServerFactory.java:331)
 |    at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.configureWebAppContext(JettyServletWebServerFactory.java:268)
 |    at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.getWebServer(JettyServletWebServerFactory.java:182)
 |    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:188)
 |    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162)
 |    ... 8 common frames omitted

Comment From: mhalbritter

Hello! Please see this section of the release notes: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes#nested-jar-support

There's a section about switching back to the old loader implementation. Does it work with the old loader?

Comment From: Nowheresly

Thank you @mhalbritter for your quick answer, this is really appreciated! Unfortunately, switching back to the old loader does not fix the issue. We still have the same exception on startup. is there anything else I could do?

Comment From: Nowheresly

Ok I think I've found the root cause of the issue.

Our spring boot app is running inside a docker image. To build the image, we use the tips explained here:

https://spring.io/blog/2018/11/08/spring-boot-in-a-container#a-better-dockerfile

Here is an extracted snippet of the Dockerfile:

FROM openjdk:17-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

It seems this approach does not work anymore with spring boot 3.2.0.

Any idea about how to proceed now ?

Comment From: mhalbritter

Does this documentation help you? https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#container-images

It uses the layertools to create an optimized docker image.

Comment From: Nowheresly

Yes, it's exactly what I was looking for. After updating my Dockerfile to use the layertools, now my spring boot app is able to start! Thank you very much for your support @mhalbritter !

Comment From: mhalbritter

Glad to hear that this worked out!

Comment From: freddiN

A big "thank you" to @mhalbritter from me: I had the same issue with the APM agent throwing exceptions like crazy (https://github.com/elastic/apm-agent-java/issues/3490), and for the longest time I suspected the eclipse temurin JDK image to be the problem. Your link to the spring boot docker image layering docs helped.