Search code examples
javaentityinputstreamrestlet

InputStream causing memory leaks


I'm using Restlet Framework but my question is more general Java question on Streams. I have this code that returns a "blob" data / file on GET HTTP request:

@Override
public Representation getBlob() {
   InputStream is = entityRepository.getEntityBlob(appId, namespace, entityType, entityId, blobName);
   Representation representation = new InputRepresentation(is);
   representation.setMediaType(MediaType.APPLICATION_OCTET_STREAM);
   representation.setSize(count);
   return representation;
}

I am also using k6.io load testing to test this resource, tested this for 1000 active connections for 10 mins and it did not have any issue, but this same machine and resource when tested for more time, hours for example, it then turns it starts eating all the memory of the machine causing it to halt eventually.

There seems to be a "leak" here but I cannot pinpoint as there is really no error at all.

Update:

This is how it looks:

public class BlobHashServerResource extends BaseServerResource implements BlobHashResource {
   @Override
   public Representation getBlob() { 
      //... 
   }
}

This BlobHashServerResource maps to

public class BackendApplication extends Application {
  @Override
  public Restlet createInboundRoot() {
     router.attach("blobs/{blobHash}", BlobHashServerResource.class);
     return router; 
  }
}

web.xml

  <servlet>
    <servlet-name>RestletServlet</servlet-name>
    <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
    <init-param>
      <param-name>org.restlet.application</param-name>
      <param-value>com.mycompany.BackendApplication </param-value>
    </init-param>
  </servlet>

Solution

  • The solution for this is to update Restlet Framework version, as this is a known InputStream issue/bug for older Restlet version, however some Restlet packages don't have the 2.4.0 version so I also indicated here the tested compatible version:

        <properties>
           <version.restlet>2.4.0</version.restlet>
        </properties>
       
        <dependencies>
           <!-- Restlet -->
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet</artifactId>
                <version>${version.restlet}</version>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.fileupload</artifactId>
                <version>${version.restlet}</version>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.servlet</artifactId>
                <version>${version.restlet}</version>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.swagger</artifactId>
                <version>${version.restlet}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.raml</groupId>
                        <artifactId>raml-parser</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.xstream</artifactId>
                <!--version>${version.restlet}</version-->
                <version>2.3.12</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.codehaus.jettison</groupId>
                        <artifactId>jettison</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>com.thoughtworks.xstream</groupId>
                        <artifactId>xstream</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.apispark</artifactId>
                <version>2.3.12</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.raml</groupId>
                        <artifactId>raml-parser</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.restlet.jee</groupId>
                <artifactId>org.restlet.ext.json</artifactId>
                <version>${version.restlet}</version>
            </dependency>
        </dependencies>