tsgrp / OpenContent

TSG's Web Services for ECM Repositories
8 stars 4 forks source link

ImageMagickTransformationImpl File Leak #44

Closed benallenallen closed 9 years ago

benallenallen commented 10 years ago

When using the ImageMagickTransformationImpl to transform to images, a temp file is created, which is not properly deleted. On a machine configured to use ImageMagick as its transformer, there will be a large number of files named something like "imageMagickTemp8783697537761902092output.png" that are not properly cleaned up.

The culprit is most likely the fact that we are using File objects when rendering, and the following two File references have a leak:

contentTemp
outputTempFile

The update is to shun the use of File Objects altogether since they are slow and prone to temp file leaks. A BufferedImage is in a way the java native representation of an image-object. Bad News: No commandline tool can deal directly with a BufferedImage. Good new: im4java uses objects of type BufferedImage transparently, if you use pass these objects at invocation time:

IMOperation op = new IMOperation();
op.addImage();                        // input
op.blur(2.0).paint(10.0);
op.addImage();                        // output

ConvertCmd convert = new ConvertCmd();
BufferedImage img = ...;
String outfile = ...;
...
convert.run(op,img,outfile);

Note that the above use of BufferedImages works fine for input-images. If you need to write to a BufferedImage, you must pipe the output of the commandline-tool to stdout, create an instance of the class org.im4java.core.Stream2BufferedImage and set it as the OutputConsumer of the command:

IMOperation op = new IMOperation();
op.addImage();                        // input
....
op.addImage("png:-");                 // output: stdout
...
images = ...;   

// set up command
ConvertCmd convert = new ConvertCmd();
Stream2BufferedImage s2b = new Stream2BufferedImage();
convert.setOutputConsumer(s2b);

// run command and extract BufferedImage from OutputConsumer
convert.run(op,(Object[]) images);
BufferedImage img = s2b.getImage();

Once the above is done, we will just need to wrap these BufferedImage objects in the proper DataHandler wrappers and we should be good to go in a faster and less leaky manner!

ghost commented 10 years ago

Fixed this issue so that the temporary files containing the image aren't used anymore. Buffered Image replaces that functionality and is correctly deleted after use.

OC-Rev-9790 CR-Ben Allen

jrubins commented 10 years ago

This causes an issue when multiple threads are trying to write to stdout at the same time apparently. Since we preload images in both directions, two at a time, we can reproduce the following error fairly easily:

convert.exe: WriteBlob Failed `-' @ error/png.c/MagickPNGErrorHandler/1805.

Reverting OC-Revision and implementing better cleanup of temporary files.

benallenallen commented 9 years ago

OC-Rev-10146 - fixed this file leak in trunk