Can't delete temp file after PDF creation.

Help
David Wang
2009-01-20
2013-05-28
  • David Wang
    David Wang
    2009-01-20

    This is probably not a common use for the jPod library, but here it is anyway...

    Let's say we want to create a PDDocument instance from a PDF file. But, I want to delete that PDF file after the Java application ends (I understand that the PDDocument instance depends on random-accessing the file, and that it therefore can't be deleted while the PDDocument instance exists). This may happen, if the PDF file is actually a temporary File, where the programmer wishes to use the delete() or deleteOnExit() methods once he is done with PDDocument.

    The problem exists when using the following code, but I image it would exist when creating any instance of an ILocator:
    File tempFileToBeDeleted = // some way of creating a file object
    tempFileToBeDeleted.deleteOnExit();
    FileLocator locator = new FileLocator(tempFileToBeDeleted);
    PDDocument.createFromLocator(locator);

    The problem is the ILocator instance has methods which create and return new Streams,Readers/Writers,and RandomAccessFiles, but these streams to the file aren't being closed when the PDDocument instance is closed/deleted. In the example above, internal to the createFromLocator() call, the FileLocator is asked to create a RandomAccessFile from the temporary file, but the PDDocument instance (as far as I can tell) never calls the close() method to terminate the randomAccessFile streams to the temporary file.

    I honestly can't say I checked the entire library to ensure that all the existing close()/delete() methods don't close these streams, but I'm pretty sure they're left open even after a call to PDDocument's close() method and ILocator's delete() method. If I missed it, my sincere apologies, someone please let me know. I'm still a great fan of the jPod libraries.

    My current solution is a hack. I have added several ArrayLists to the FileLocator class. This maintains a record of all the streams that instance creates, and closes them when FileLocator's delete() method is called.

    Note: I can't remember the bug number, but there is supposedly a known bug/feature request to have File's shutdown hook ensure streams are closed before the associated file is deleted. But, I know this hasn't been fixed/implemented as of JDK EE 6, update 10.

     
    • Waldemar Dick
      Waldemar Dick
      2009-01-20

      Hi,

      I ran following code without any problems:

      File tempFile = File.createTempFile("tmp", ".pdf");
      copy(new File("OT14725389271.pdf"), tempFile);
      tempFile.deleteOnExit();

      FileLocator fileLocator = new FileLocator(tempFile);
      PDDocument pdDocument = PDDocument.createFromLocator(fileLocator);
      // do something the with document to open the random access reader
      PDPage page = pdDocument.getPageTree().getFirstPage();
      // close() closes the random access reader held in STDocument
      pdDocument.close();

      boolean deletedTempFile = tempFile.delete();
      if (!deletedTempFile) {
          System.out.println("temp file not deleted");
      }

      tempFile.delete() always worked fine and delete the temporary file.

      PDDocument will not close the random access reader by itself. You have to call its close() method to free all resources.

      You wrote:
      "I honestly can't say I checked the entire library to ensure that all the existing close()/delete() methods don't close these streams, but I'm pretty sure they're left open even after a call to PDDocument's close() method and ILocator's delete() method."

      Can you please post any test code, where the problem exists, so I can debug it. If the code is confidential, you can send it to me by email (sourceforge @ devmue.de).

      Some words on FileLocator: every call to get*Stream() opens a new stream, which must be closed by the caller. The delete() method fails as long as open streams exists. FileLocator doesn't keep track of streams it opened.

      I'm sorry I couldn't help you, but hopefully I can do a better job when I see the test code.

      Waldemar Dick

       
    • David Wang
      David Wang
      2009-01-22

      My apologies,

      You are absolutely correct. This is not a bug with jPod. I should have done more digging before posting this bug.

      In a multithreaded app, I was trying to make sure in the situation where the user force quits the application everything is still cleaned up. It looks like the shutdown hook I had registered for "pdDocument.close()" was executing after a separate hook that called "delete()" or "deleteOnExit()". Which is a separate problem of mine.

      When the code is executed in the obviously correct order, close then delete, everything works great.

      Thank you for helping me find my oversight.