Describe the bug
Some 3rd-party libs use ClassLoader.getSystemResourceAsStream to get resources from a given path inside the JAR.
Expected behavior
It works when running Quarkus with java -jar, but returns null with mvn compile quarkus:dev
Actual behavior
ClassLoader.getSystemResourceAsStream should not return null when mvn compile quarkus:dev is used
To Reproduce
Steps to reproduce the behavior:
1.
mvn io.quarkus:quarkus-maven-plugin:0.15.0:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=getting-started \
-DclassName="org.acme.quickstart.GreetingResource" \
-Dpath="/hello"
src/main/resources/META-INF/file.txt containing anything you like@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public InputStream hello() throws Exception {
return ClassLoader.getSystemResourceAsStream("META-INF/file.txt");
}
}
curl http://localhost:8080/helloYou should be using Thread.currentThread().getContextClassLoader().getResourceAsStream(). Resources inside the deployment are not on the system class path in dev mode, as we need a new class loader to enable hot deployment.
Note that this code won't work in application servers such as WildFly either.
@stuartwdouglas The code falls back to ServletContext.getResource() which doesn't work either, maybe that needs to be fixed?
This is the filter implementation: https://github.com/paultuckey/urlrewritefilter/blob/master/src/main/java/org/tuckey/web/filters/urlrewrite/UrlRewriteFilter.java#L264
So the ServletContext.getResource() will serve out of META-INF/resources, so META-INF/resource/META-INF/file.txt would work.
Because this is a jar and not a war there is not really a standard layout. We can't serve from the root of the jar because that is where all the class files are, and we don't want to serve them to the outside world. META-INF/resources is a standard location according to the Servlet spec, so that is why I picked this.
That makes sense to me. I'll close this issue for now. Thank you @stuartwdouglas
Most helpful comment
You should be using Thread.currentThread().getContextClassLoader().getResourceAsStream(). Resources inside the deployment are not on the system class path in dev mode, as we need a new class loader to enable hot deployment.
Note that this code won't work in application servers such as WildFly either.