quarkus icon indicating copy to clipboard operation
quarkus copied to clipboard

Undertow: servletContext.getResourcePaths("/") not listed in PROD mode

Open melloware opened this issue 2 years ago • 14 comments

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?

quarkus-servlet.zip

  1. Unzip the reproducer attached
  2. Run mvn clean quarkus:dev and see the servlet paths printed out 2022-12-27 13:00:20,489 INFO [org.acm.ApplicationInitializer] (Quarkus Main Thread) Resource: /index.html
  3. Run mvn clean package -DskipTests && java -jar target/quarkus-app/quarkus-run.jar and see the WARNING that no paths found 2022-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

melloware avatar Sep 17 '22 11:09 melloware

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

melloware avatar Sep 20 '22 12:09 melloware

@manovotn was hoping you could look at this one?

melloware avatar Dec 26 '22 19:12 melloware

@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 :⁠-⁠)

manovotn avatar Dec 26 '22 21:12 manovotn

Sorry @manovotn you answered on the other Undertow ticket but it should have been @mkouba !

melloware avatar Dec 26 '22 21:12 melloware

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 :⁠-⁠)

manovotn avatar Dec 26 '22 21:12 manovotn

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 ;-)

mkouba avatar Dec 28 '22 10:12 mkouba

@stuartwdouglas bump ?

melloware avatar Jan 16 '23 22:01 melloware

This bug is still happening in 999-SNAPSHOT.

melloware avatar Apr 28 '23 14:04 melloware

@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

melloware avatar Jun 07 '23 12:06 melloware

I just submitted another fix: https://github.com/quarkusio/quarkus/pull/34611

melloware avatar Jul 07 '23 17:07 melloware

@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

image

Here is that line in the debugger:

image

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()

melloware avatar Jul 08 '23 12:07 melloware

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.

tony-in-nz avatar Aug 13 '23 03:08 tony-in-nz