Temporary files are not getting deleted in Apache Jackrabbit

764 views Asked by At

I am using Apache Jackrabbit to store PDF, doc files and using FileDataStore as underlying data store. After setting the binary data values many temporary/spool files (bin*.tmp) are getting created in the temp directory. These files are never getting deleted until JVM is getting shutdown. These temp files are flooding the tmp directory and resulting to a no space left on device error.

Following is the code snippet:

Node childFileNode = childLeafFolder.addNode(file.pdf, NodeType.NT_FILE);
Node childContentNode = childFileNode.addNode(Node.JCR_CONTENT,
                    NodeType.NT_RESOURCE);
Property property = childContentNode.setProperty(Property.JCR_DATA, binary); 

I have tried invoking property.getBinary.dispose(), which points to AbstractQValue dispose(), and find out that it is an empty method.

I have googled and came across JCR-3568 and this is still unresolved. My application runs for long duration and it can not be shutdown frequently.

Looks like I am missing some thing as this could be a very common issue.

1

There are 1 answers

0
Ivan Ravin On

There is resource leak in jackrabbit-spi-commons library, and it still not fixed. When you write file to server and file size more than 64kb, client library creates 2 copy of original file in temporary folder, but deletes only 1. While it not fixed, you can use workaround:

public class JcrHelper {
    public static Value createBinaryValue(Session jcrSession, InputStream in) throws UnsupportedRepositoryOperationException, RepositoryException {
        ValueFactory valueFactory = jcrSession.getValueFactory();
        Value value = valueFactory.createValue(in);
        return value;
    }
    public static void discardBinary(Value value) {
        if (value instanceof QValueValue) {
            QValueValue qValueValue = (QValueValue)value;
            qValueValue.getQValue().discard();
        }
    }
}

and in code you should use Value instead Binary:

Value value = JcrHelper.createBinaryValue(jcrSession, inputStream);
try {
    contentNode.setProperty(Property.JCR_DATA, value);
    jcrSession.save();
} finally {
    JcrHelper.discardBinary(value);
}

JcrHelper class uses deprecated method, and violates encapsulation, but code not leaky. I think its only possible workaround while leak in Binary implementation not fixed. Furthermore, this code creates only 1 copy of your file in temp folder (will be deleted on GC)