You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by "Emmeran Seehuber (Jira)" <ji...@apache.org> on 2021/03/08 16:42:00 UTC

[jira] [Commented] (PDFBOX-4202) PDDocument is closed before calling close()

    [ https://issues.apache.org/jira/browse/PDFBOX-4202?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17297518#comment-17297518 ] 

Emmeran Seehuber commented on PDFBOX-4202:
------------------------------------------

As I see this problem in production too (but made a workaround long ago by just retrying to create the PDF later again), I now know whats going on. As [~cgao] found out the document must be pinned so that it is not garbage collected. In my case I use the LayerUtility to import pages as XForm to stamp them into a new PDDocument. If the "source" PDDocument goes away because of GC the XForm becomes invalid. This problem is hard to reproduce, as it needs some GC cycles to get the finalizer running.

COSDocument has a finalizer. Which is bad and has been official deprecated as of Java 9 (see e.g. https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#finalize–). Well, it has always been bad because of the GC pressure and other problems it causes.  

The finalizer() in COSDocument is more or less only used to give a warning. But it closes all child resources/objects, even if there are still references to them. But it should not do this, as all OS resources are freed by the finalizer on the individual OS resource objects (FileDescriptors, ...). As of Java 9 the JDK got more or less rid of finalizers. 

The clean fix would be  to only log the warning message. See also [https://softwareengineering.stackexchange.com/questions/288715/is-overriding-object-finalize-really-bad] 

With Java 9 the finalizer can be replaced with PhantomReferences and Cleaner usages. As Java 9 did internally. Which is of course not yet possible in trunk on Java 8.

Also maybe PDDocument in trunk should implement AutoCloseable so that IDEs give warnings if one does not care to close it.

> PDDocument is closed before calling close()
> -------------------------------------------
>
>                 Key: PDFBOX-4202
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-4202
>             Project: PDFBox
>          Issue Type: Bug
>          Components: PDModel
>    Affects Versions: 2.0.9
>         Environment: WIndow 10 x64
>            Reporter: Chenyue Gao
>            Priority: Critical
>
>  
> The following code append PDDocument read from a file to the mainDocument which is passed as parameter. When I save the mainDocument, it throws the exception below. 
> {code:java}
> public static void addPDPage(PDDocument mainDocument, File file, int pagenum) throws IOException {
>     PDDocument pkDocument = PDDocument.load(file);
>     PDPageTree pdpageTree = pkDocument.getPages();
>     pdpageTree.forEach(page -> {
>          mainDocument.addPage(page);
>     });
> }
> {code}
> It seems that the pkDocument inside this function automatically closed itself due to Java garbage collection. As a result the mainDocument can't save the page associated with the pkDocument.
> A workaround could be to return pkDcoument to the caller and keep the reference at the same level of mainDocument until mainDocument saves
>  
>  
> [2018-04-16 11:11:58] COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
>  [2018-04-16 11:11:58] java.io.IOException: COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
>  at org.apache.pdfbox.cos.COSStream.checkClosed(COSStream.java:77)
>  at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:125)
>  at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1200)
>  at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:383)
>  at org.apache.pdfbox.cos.COSObject.accept(COSObject.java:158)
>  at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
>  at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
>  at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
>  at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1096)
>  at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
>  at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1367)
>  at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1254)
>  at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1232)
>  at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1204)
>  at com.commands.PrintPackingSlipToPDFCommand.run(PrintPackingSlipToPDFCommand.java:116)
>  at com.commands.AbstractCommand.execute(AbstractCommand.java:74)
>  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>  at java.lang.reflect.Method.invoke(Unknown Source)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@pdfbox.apache.org
For additional commands, e-mail: dev-help@pdfbox.apache.org