Index: trunk/src/java/org/apache/fop/render/pdf/pdfbox/PreloaderPDF.java
===================================================================
--- trunk/src/java/org/apache/fop/render/pdf/pdfbox/PreloaderPDF.java	(revision 1784343)
+++ trunk/src/java/org/apache/fop/render/pdf/pdfbox/PreloaderPDF.java	(working copy)
@@ -60,8 +60,6 @@
 
     private static Map<Object, Cache<URI, PDDocument>> documentCacheMap
             = Collections.synchronizedMap(new WeakHashMap<Object, Cache<URI, PDDocument>>());
-    //the cache here can cause problems because PDDocument that have been closed might still
-    //be accessed. Example: java.io.IOException: The handle is invalid
 
     /** {@inheritDoc} */
     public ImageInfo preloadImage(String uri, Source src, ImageContext context)
@@ -162,7 +160,12 @@
     private PDDocument getDocument(Object context, URI uri, Source src)
             throws IOException {
         try {
-            return getDocumentCache(context).getValue(uri, createDocumentMaker(src, uri));
+            PDDocument pddoc = getDocumentCache(context).getValue(uri, createDocumentMaker(src, uri));
+            if (pddoc.getDocument().isClosed()) {
+                removeDocumentCache(context);
+                pddoc = getDocumentCache(context).getValue(uri, createDocumentMaker(src, uri));
+            }
+            return pddoc;
         } catch (IOException ioe) {
             throw ioe;
         } catch (Exception e) {
@@ -171,6 +174,10 @@
         }
     }
 
+    private void removeDocumentCache(Object context) {
+        documentCacheMap.remove(context);
+    }
+
     private Cache<URI, PDDocument> getDocumentCache(Object context) {
         Cache<URI, PDDocument> documentCache = documentCacheMap.get(context);
 
Index: trunk/test/java/org/apache/fop/render/pdf/PDFImageTestCase.java
===================================================================
--- trunk/test/java/org/apache/fop/render/pdf/PDFImageTestCase.java	(nonexistent)
+++ trunk/test/java/org/apache/fop/render/pdf/PDFImageTestCase.java	(working copy)
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.fop.render.pdf;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.io.BufferedOutputStream;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+
+import org.xml.sax.SAXException;
+
+import static org.junit.Assert.assertNull;
+import org.junit.Test;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+public class PDFImageTestCase {
+    private File foBaseDir = new File("test/resources");
+    private File pdfBaseDir = new File("test/test-reports");
+    private File configFile = new File("test/resources/test.xconf");
+
+    protected final FopFactory fopFactory;
+    protected final TransformerFactory tFactory ;
+
+    public PDFImageTestCase() throws SAXException, IOException {
+        fopFactory = FopFactory.newInstance(configFile);
+        tFactory = TransformerFactory.newInstance();
+        pdfBaseDir.mkdirs();
+    }
+
+    /**
+     * Create an FOUserAgent for our tests
+     * @return an initialized FOUserAgent
+     */
+    protected FOUserAgent getUserAgent() {
+        final FOUserAgent a = fopFactory.newFOUserAgent();
+        return a;
+    }
+
+    /**
+     * Create an FOUserAgent for our tests with image cache cleared
+     * @return an initialized FOUserAgent
+     */
+    protected FOUserAgent getUserAgentImageCacheCleared() {
+        final FOUserAgent a = fopFactory.newFOUserAgent();
+        a.getImageManager().getCache().clearCache();
+        return a;
+    }
+
+    /**
+     * Test PDF image cache
+     * @throws Exception checkstyle wants a comment here, even a silly one
+     */
+    @Test
+    public void testPDFImageCache() throws Exception {
+        File foFile = new File(foBaseDir, "pdf-image.fo");
+
+        // First run
+        File firstRunFile = new File(pdfBaseDir, "pdf-image-first.pdf");
+        convertFO(foFile, firstRunFile, getUserAgent());
+        BufferedImage firstRunImage = getImageFromPDF(firstRunFile, 0);
+
+        // Use cache
+        File secondRunFile = new File(pdfBaseDir, "pdf-image-second.pdf");
+        convertFO(foFile, secondRunFile, getUserAgent());
+        BufferedImage secondRunImage = getImageFromPDF(secondRunFile, 0);
+
+        // Multiple runs, after clearing cache
+        File clearedRunFile1 = new File(pdfBaseDir, "pdf-image-cleared-1.pdf");
+        java.lang.System.gc(); // force gc, to cleanup cache
+        convertFO(foFile, clearedRunFile1, getUserAgentImageCacheCleared());
+        
+        File clearedRunFile2 = new File(pdfBaseDir, "pdf-image-cleared-2.pdf");
+        java.lang.System.gc(); // force gc, to cleanup cache
+        convertFO(foFile, clearedRunFile2, getUserAgentImageCacheCleared());
+        
+        File clearedRunFile3 = new File(pdfBaseDir, "pdf-image-cleared-3.pdf");
+        java.lang.System.gc(); // force gc, to cleanup cache
+        convertFO(foFile, clearedRunFile3, getUserAgentImageCacheCleared());
+        
+        BufferedImage clearedImage = getImageFromPDF(clearedRunFile3, 0);
+
+        // Original vs cached image
+        assertNull(diffImages(firstRunImage, secondRunImage));
+
+        // Original vs cleared cached image
+        assertNull(diffImages(firstRunImage, clearedImage));
+    }
+
+    /** 
+     * Get Image from PDF using PDFBox
+     * @param pdfFile PDF file to get image
+     * @param page which page to get image.
+     *
+     * @return Buffered Image
+     *
+     * @throws IOException
+     */
+    private BufferedImage getImageFromPDF(File pdfFile, int page) throws IOException {
+        PDDocument document = null;
+        BufferedImage image = null;
+        try {
+            document = PDDocument.load(pdfFile, (String)null);
+            PDFRenderer renderer = new PDFRenderer(document);
+            image = renderer.renderImage(page);
+        } finally {
+            if (document != null) {
+                document.close();
+            }
+        }
+        return image;
+    }
+
+    /**
+     * Convert a test FO file to PDF file
+     * @param foFile the FO file
+     * @param pdfFile the generated PDF file
+     * @param ua the preconfigured user agent
+     * @throws Exception if the conversion fails
+     */
+    protected void convertFO(File foFile, File pdfFile, FOUserAgent ua)
+            throws Exception {
+        BufferedOutputStream bos = null;
+        try {
+            bos = new java.io.BufferedOutputStream(new FileOutputStream(pdfFile));
+            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, ua, bos);
+            Source src = new StreamSource(foFile);
+            SAXResult res = new SAXResult(fop.getDefaultHandler());
+
+            Transformer transformer = tFactory.newTransformer();
+            transformer.transform(src, res);
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+        }
+    }
+
+    /**
+     * Get the difference between two images, identical colors are set to white, differences are
+     * xored, the highest bit of each color is reset to avoid colors that are too light
+     *
+     * Copied from: pdfbox\src\test\java\org\apache\pdfbox\rendering\TestPDFToImage.java
+     *
+     * @param bim1
+     * @param bim2
+     * @return If the images are different, the function returns a diff image If the images are
+     * identical, the function returns null If the size is different, a black border on the botton
+     * and the right is created
+     *
+     * @throws IOException
+     */
+    private BufferedImage diffImages(BufferedImage bim1, BufferedImage bim2) throws IOException
+    {
+        int minWidth = Math.min(bim1.getWidth(), bim2.getWidth());
+        int minHeight = Math.min(bim1.getHeight(), bim2.getHeight());
+        int maxWidth = Math.max(bim1.getWidth(), bim2.getWidth());
+        int maxHeight = Math.max(bim1.getHeight(), bim2.getHeight());
+        BufferedImage bim3 = null;
+        if (minWidth != maxWidth || minHeight != maxHeight)
+        {
+            bim3 = createEmptyDiffImage(minWidth, minHeight, maxWidth, maxHeight);
+        }
+        for (int x = 0; x < minWidth; ++x)
+        {
+            for (int y = 0; y < minHeight; ++y)
+            {
+                int rgb1 = bim1.getRGB(x, y);
+                int rgb2 = bim2.getRGB(x, y);
+                if (rgb1 != rgb2
+                        // don't bother about differences of 1 color step
+                        && (Math.abs((rgb1 & 0xFF) - (rgb2 & 0xFF)) > 1
+                        || Math.abs(((rgb1 >> 8) & 0xFF) - ((rgb2 >> 8) & 0xFF)) > 1
+                        || Math.abs(((rgb1 >> 16) & 0xFF) - ((rgb2 >> 16) & 0xFF)) > 1))
+                {
+                    if (bim3 == null)
+                    {
+                        bim3 = createEmptyDiffImage(minWidth, minHeight, maxWidth, maxHeight);
+                    }
+                    int r = Math.abs((rgb1 & 0xFF) - (rgb2 & 0xFF));
+                    int g = Math.abs((rgb1 & 0xFF00) - (rgb2 & 0xFF00));
+                    int b = Math.abs((rgb1 & 0xFF0000) - (rgb2 & 0xFF0000));
+                    bim3.setRGB(x, y, 0xFFFFFF - (r | g | b));
+                }
+                else
+                {
+                    if (bim3 != null)
+                    {
+                        bim3.setRGB(x, y, Color.WHITE.getRGB());
+                    }
+                }
+            }
+        }
+        return bim3;
+    }
+
+    /**
+     * Create an image; the part between the smaller and the larger image is painted black, the rest
+     * in white
+     *
+     * Copied from: pdfbox\src\test\java\org\apache\pdfbox\rendering\TestPDFToImage.java
+     *
+     * @param minWidth width of the smaller image
+     * @param minHeight width of the smaller image
+     * @param maxWidth height of the larger image
+     * @param maxHeight height of the larger image
+     *
+     * @return
+     */
+    private BufferedImage createEmptyDiffImage(int minWidth, int minHeight, int maxWidth, int maxHeight)
+    {
+        BufferedImage bim3 = new BufferedImage(maxWidth, maxHeight, BufferedImage.TYPE_INT_RGB);
+        Graphics graphics = bim3.getGraphics();
+        if (minWidth != maxWidth || minHeight != maxHeight)
+        {
+            graphics.setColor(Color.BLACK);
+            graphics.fillRect(0, 0, maxWidth, maxHeight);
+        }
+        graphics.setColor(Color.WHITE);
+        graphics.fillRect(0, 0, minWidth, minHeight);
+        graphics.dispose();
+        return bim3;
+    }
+}
Index: trunk/test/resources/pdf-image.fo
===================================================================
--- trunk/test/resources/pdf-image.fo	(nonexistent)
+++ trunk/test/resources/pdf-image.fo	(working copy)
@@ -0,0 +1,36 @@
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"  font-selection-strategy="character-by-character">
+    <fo:layout-master-set>
+        <fo:simple-page-master margin-bottom="1in" margin-left="1in" margin-right="1in" margin-top="1in" master-name="section1-first-page" page-height="11in" page-width="8.5in">
+            <fo:region-body margin-bottom="0.5in" margin-top="0.5in"/>
+            <fo:region-before extent="0.5in" region-name="first-page-header"/>
+            <fo:region-after extent="0.5in" region-name="first-page-footer"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master margin-bottom="1in" margin-left="1in" margin-right="1in" margin-top="1in" master-name="section1-odd-page" page-height="11in" page-width="8.5in">
+            <fo:region-body margin-bottom="0.5in" margin-top="0.5in"/>
+            <fo:region-before extent="0.5in" region-name="odd-page-header"/>
+            <fo:region-after extent="0.5in" region-name="odd-page-footer"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master margin-bottom="1in" margin-left="1in" margin-right="1in" margin-top="1in" master-name="section1-even-page" page-height="11in" page-width="8.5in">
+            <fo:region-body margin-bottom="0.5in" margin-top="0.5in"/>
+            <fo:region-before extent="0.5in" region-name="even-page-header"/>
+            <fo:region-after extent="0.5in" region-name="even-page-footer"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="section1-page-sequence-master">
+            <fo:single-page-master-reference master-reference="section1-first-page"/>
+            <fo:repeatable-page-master-alternatives>
+                <fo:conditional-page-master-reference master-reference="section1-odd-page" odd-or-even="odd"/>
+                <fo:conditional-page-master-reference master-reference="section1-even-page" odd-or-even="even"/>
+            </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+    </fo:layout-master-set>
+    <fo:page-sequence hyphenate="false" language="en" master-reference="section1-page-sequence-master">
+        <fo:flow flow-name="xsl-region-body">
+            <fo:block>
+                <fo:external-graphic content-height="scale-to-fit" 
+                                     content-width="scale-to-fit" 
+                                     inline-progression-dimension.maximum="100%" 
+                                     src="file:test/resources/image.pdf"/>
+            </fo:block>
+        </fo:flow>
+    </fo:page-sequence>
+</fo:root>
\ No newline at end of file
Index: trunk/test/resources/test.xconf
===================================================================
--- trunk/test/resources/test.xconf	(nonexistent)
+++ trunk/test/resources/test.xconf	(working copy)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+
+  <!-- Switch off font caching for the purposes of unit testing -->
+  <use-cache>false</use-cache>
+  <font-base>.</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <filterList type="tiff">
+        <value>ascii-85</value>
+      </filterList>
+      <filterList type="default">
+        <value>null</value>
+      </filterList>
+      <filterList type="image">
+        <value>null</value>
+      </filterList>
+      <filterList type="content">
+        <value>null</value>
+      </filterList>
+    </renderer>
+  </renderers>
+</fop>
