quarkus
quarkus copied to clipboard
Undertow: servletContext.getResourcePaths("/") not listed in PROD mode
Describe the bug
I have a simple ApplicationInitializer to print out all the available servlet resource paths...
public class ApplicationInitializer implements ServletContainerInitializer {
private static final Logger logger = Logger.getLogger(ApplicationInitializer.class.getName());
@Override
public void onStartup(Set<Class<?>> c, ServletContext servletContext) throws ServletException {
logger.info("Checking servlet resource paths...");
Set<String> resourcePaths = servletContext.getResourcePaths("/");
for (String resourcePath : resourcePaths) {
logger.info("Resource: " + resourcePath);
}
if (resourcePaths.isEmpty()) {
logger.warning("NO servlet resource paths found!");
}
}
}
When running in DEV mode mvn quarkus:dev
the following is printed out it finds the mapped /index.html
:
2022-09-17 07:51:08,575 INFO [org.acm.ApplicationInitializer] (Quarkus Main Thread) Checking servlet resource paths...
2022-09-17 07:51:08,577 INFO [org.acm.ApplicationInitializer] (Quarkus Main Thread) Resource: /index.html
When running in PRD mode mvn clean package -DskipTests && java -jar target/quarkus-app/quarkus-run.jar
it doesn't find anything:
2022-09-17 07:49:05,376 INFO [org.acm.ApplicationInitializer] (main) Checking servlet resource paths...
2022-09-17 07:49:05,376 WARNING [org.acm.ApplicationInitializer] (main) NO servlet resource paths found!
Expected behavior
All servlet resource paths should be available in both DEV and PRD mode.
Actual behavior
Resource Paths are only available in DEV mode.
How to Reproduce?
- Unzip the reproducer attached
- Run
mvn clean quarkus:dev
and see the servlet paths printed out2022-12-27 13:00:20,489 INFO [org.acm.ApplicationInitializer] (Quarkus Main Thread) Resource: /index.html
- Run
mvn clean package -DskipTests && java -jar target/quarkus-app/quarkus-run.jar
and see the WARNING that no paths found2022-12-27 13:01:06,297 WARNING [org.acm.ApplicationInitializer] (main) NO servlet resource paths found!
Output of uname -a
or ver
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Output of java -version
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.10+9, mixed mode)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.15.1
Build tool (ie. output of mvnw --version
or gradlew --version
)
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0) Maven home: C:\Tools\apache-maven-3.8.5 Java version: 11.0.10, vendor: AdoptOpenJDK, runtime: C:\Tools\jdk-11.0.10 Default locale: en_US, platform encoding: Cp1252 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Additional information
No response
cc @sberyozkin @stuartwdouglas
I have a feeling the bug is right here especially since there is a TODO
still there about in PRD mode its not scanning the JARs properly for files but it is in DEV mode because its looking at the File Paths.
https://github.com/quarkusio/quarkus/blob/9ed77a64d671b65db866ea6759a7cb06c94bd7d5/extensions/undertow/runtime/src/main/java/io/quarkus/undertow/runtime/UndertowDeploymentRecorder.java#L184-L196
@manovotn was hoping you could look at this one?
@melloware not sure how you arrived at my name as I haven't done much in Undertow, but I could take a look once I am back from X-mass break. I am unlikely to know though as I am unfamiliar with UT codebase :-)
Sorry @manovotn you answered on the other Undertow ticket but it should have been @mkouba !
No problem. Like I said, I can take a look once I am operational again. I think Martin will be in very much the same situation :-)
I believe that the problem lies in the DirectoryResource#list() method. It returns an empty list because the KnownPathResourceManager#files
looks like ["index.html"]
. I don't think that NavigableSet.headSet(String)
could be used here but maybe I've overlooked something.
@stuartwdouglas could you pls take a look sometime next year ;-)
@stuartwdouglas bump ?
This bug is still happening in 999-SNAPSHOT.
@stuartwdouglas just found another bug with all your latest changes that was working:
https://github.com/melloware/quarkus-faces/issues/282
Basically I have resources in \META-INF\resources\java\org\primefaces\showcase\convert\CountryConverter.java
as I copy the Java files there so they can be displayed. In Windows it can find the resource but in Linux with the exact same JAR file it fails in Linux.
Windows Works:
java -jar target/quarkus-app/quarkus-run.jar
Linux with same JAR fails:
java -jar target/quarkus-app/quarkus-run.jar
Error:
An error occured while initializing MyFaces: Unable to get listed resource java\org\primefaces\showcase\convert\CountryConverter.java from directory for path from underlying manager io.undertow.server.handlers.resource.ClassPathResourceManager@5c059a68: java.lang.RuntimeException: Unable to get listed resource java\org\primefaces\showcase\convert\CountryConverter.java from directory for path from underlying manager io.undertow.server.handlers.resource.ClassPathResourceManager@5c059a68
2023-06-07 14:24:34 at io.quarkus.undertow.runtime.KnownPathResourceManager$DirectoryResource.list(KnownPathResourceManager.java:151)
2023-06-07 14:24:34 at io.undertow.server.handlers.resource.CachedResource.list(CachedResource.java:110)
Reported: https://github.com/melloware/quarkus-faces/issues/282
I just submitted another fix: https://github.com/quarkusio/quarkus/pull/34611
@stuartwdouglas I finally got to the bottom of this but have no idea how to fix it. I debugged the code in production mode and its finding the resource correctly using KnownPathResourceManager
but in Undertow ServletContextImpl.getResourcePaths()
it is returning a URLResource
and calling Path file = res.getFilePath();
on that URL resource which ALWAYS returns null.
Resource: jar:file:/C:/temp/quarkus-servlet/target/quarkus-app/app/code-with-quarkus-1.0.0-SNAPSHOT.jar!/META-INF/resources/index.html
getFilePath(): NULL !!!
Undertow Code: https://github.com/undertow-io/undertow/blob/master/servlet/src/main/java/io/undertow/servlet/spec/ServletContextImpl.java#L278
Here is that line in the debugger:
So basically a URL resource jar:file:/C:/temp/quarkus-servlet/target/quarkus-app/app/code-with-quarkus-1.0.0-SNAPSHOT.jar!/META-INF/resources/index.html
returns NULL for getFilePath()
Fails for me on Windows (build and deploy to Ubuntu server). Sent the code to mate with a mac to build and deploy on the Ubuntu server and it worked.