Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-1138

Stream prematurely closed by finalizer

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 3.0.23.Final, 3.1.3.Final
    • 3.0.10.Final
    • jaxrs
    • None
    • Hide

      using intermediate variable which stores Response and InputStream object before consuming

      Show
      using intermediate variable which stores Response and InputStream object before consuming

      There's a problem when invoking jaxrs service returning "big enough" Streams (depends on platform, it is generally over 1Mo). There's an "InputStream closed" Exception that sounds like premature closing by java finalizer. Details :

      Caused by: java.lang.RuntimeException: java.io.IOException: Stream closed
                      at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.loadHttpMethod(ApacheHttpClient4Engine.java:381)
                      at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:232)
                      ... 21 more
      Caused by: java.io.IOException: Stream closed
                      at java.io.BufferedInputStream.getBufIfOpen(Unknown Source)
                      at java.io.BufferedInputStream.read(Unknown Source)
                      at org.jboss.resteasy.client.core.SelfExpandingBufferredInputStream.read(SelfExpandingBufferredInputStream.java:57)
                      at java.io.FilterInputStream.read(Unknown Source)
                      at org.jboss.resteasy.client.core.SelfExpandingBufferredInputStream.read(SelfExpandingBufferredInputStream.java:67)
                      at org.jboss.resteasy.plugins.providers.ProviderHelper.writeTo(ProviderHelper.java:124)
                      at org.jboss.resteasy.plugins.providers.DataSourceProvider.writeTo(DataSourceProvider.java:197)
                      at org.jboss.resteasy.plugins.providers.DataSourceProvider.writeTo(DataSourceProvider.java:31)
                      at org.jboss.resteasy.plugins.providers.multipart.AbstractMultipartWriter.writePart(AbstractMultipartWriter.java:60)
                      at fr.gouv.diplomatie.client.rest.utils.MultipartFormDataWriter.writePart(MultipartFormDataWriter.java:33)
                      at org.jboss.resteasy.plugins.providers.multipart.AbstractMultipartFormDataWriter.writeParts(AbstractMultipartFormDataWriter.java:33)
                      at org.jboss.resteasy.plugins.providers.multipart.AbstractMultipartWriter.write(AbstractMultipartWriter.java:33)
                      at org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataWriter.writeTo(MultipartFormDataWriter.java:34)
                      at org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataWriter.writeTo(MultipartFormDataWriter.java:18)
      

      Our service interface is defined by :

      @javax.ws.rs.GET
      @javax.ws.rs.Path(value="/document/{documentId}/content")
      @javax.ws.rs.Produces(value={"application/octet-stream"})
      public abstract javax.ws.rs.core.Response readContent(@javax.ws.rs.PathParam(value="documentId") java.lang.String id);
      

      And a sample usecase is :

      IOUtils.copy(service.readContent(id).readEntity(InputStream.class), fileOut);
      

      I have seen old issues about finalizer in ClientResponse class... so i tryed this silly thing and it works !

      Response res = service.readContent(id);
      InputStream is = res.readEntity(InputStream.class);
      IOUtils.copy(is, fileOut);
      

      there's some JVM tricks behin...managing automatic stream closing appears to be hard to solve ! It could be better to leave responsibility of cleanup to caller (managed with "try-with-resource" java pattern or IOUtils lib)

            rhn-support-asoldano Alessio Soldano
            grisha78 gregory picavet (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: