Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuarkusClassLoader.getResourceAsStream does not work with directories in quarkus:dev #11707

Closed
crissi98 opened this issue Aug 28, 2020 · 2 comments · Fixed by #11716
Closed
Labels
kind/bug Something isn't working
Milestone

Comments

@crissi98
Copy link

Describe the bug
When your try to read a directory from the resources-folder using Thread.currentThread().getContextClassLoader().getResourceAsStream("test"), an IOException occurs. The directory can not be read as an InputStream, because the class Loaders uses Files.readAllBytes, which does not work with directories.

Expected behavior
According to the Java Spec, getResourceAsStream("test") should the same as getResource("test").openStream().

Actual behavior
When I use getResource("test").openStream() the InputStream is returned properly, but getResourceAsStream("test"). The follwing Exeception occurs

2020-08-28 11:55:57,017 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /load/1 failed, error id: 4ca207b6-2f6f-4ad6-89c8-efe7959e90d3-3: org.jboss.resteasy.spi.UnhandledException: java.lang.RuntimeException: Unable to read /Users/christianradow/IntelliJ/classloader-test/target/classes/test
        at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
        at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:515)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
        at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at java.base/java.lang.Thread.run(Thread.java:834)
        at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: java.lang.RuntimeException: Unable to read /Users/christianradow/IntelliJ/classloader-test/target/classes/test
        at io.quarkus.bootstrap.classloading.DirectoryClassPathElement$1.getData(DirectoryClassPathElement.java:108)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.getResourceAsStream(QuarkusClassLoader.java:337)
        at org.acme.quarkus.sample.ClassLoaderTestResource.testDirectory1(ClassLoaderTestResource.java:19)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:638)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:504)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:454)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:456)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:417)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
        ... 20 more
Caused by: java.io.IOException: Is a directory
        at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
        at java.base/sun.nio.ch.FileDispatcherImpl.read(FileDispatcherImpl.java:48)
        at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:276)
        at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:245)
        at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:223)
        at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:65)
        at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:109)
        at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
        at java.base/java.nio.file.Files.read(Files.java:3158)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3212)
        at io.quarkus.bootstrap.classloading.DirectoryClassPathElement$1.getData(DirectoryClassPathElement.java:100)
        ... 37 more

To Reproduce
Steps to reproduce the behavior:

  1. Create a directory named test in the resources folder
  2. Use the following Resource:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.io.InputStream;

@Path("/load")
public class ClassLoaderTestResource {

    // Does not work using quarkus:dev
    @GET
    @Path("/1")
    @Produces(MediaType.TEXT_PLAIN)
    public String testDirectory1() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream testResource = loader.getResourceAsStream("test");
        return testResource.toString();
    }

    // Works using quarkus:dev
    @GET
    @Path("/2")
    @Produces(MediaType.TEXT_PLAIN)
    public String testDirectory2() throws IOException {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream testResource = loader.getResource("test").openStream();
        return testResource.toString();
    }

}
  1. Start the project using quarkus:dev
  2. Test the /load/1 endpoint to reproduce the bug.

Configuration

# No additional config

Environment (please complete the following information):

  • tested on both Windows 10 and MacOS
  • Output of java -version: openjdk version "11.0.2" 2019-01-15
  • Quarkus version or git rev: tested on multiple Versions from 1.3.1.Final to 1.7.1.Final
  • Build tool (ie. output of mvnw --version or gradlew --version): Apache Maven 3.6.3

Additional context
The problem occurs because the directory is read using Files.readAllBytes(), which produces an IOException.

@jaikiran
Copy link
Member

I've opened #11716 with a potential fix.

@gsmet gsmet modified the milestones: 1.8.0.CR1, 1.7.2.Final Sep 2, 2020
@eriknyk
Copy link

eriknyk commented Jul 30, 2021

the issue is still happening in v2.1.0.Final

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants