0

当我测试我的文档时,有时,我检查有时我有以下异常(不是每次,有时,但我不明白它什么时候发生,为什么会发生。我只有那个错误日志:

例外是在这条线上

void org.apache.pdfbox.pdmodel.PDDocument.saveIncremental(FileInputStream 输入,OutputStream 输出)

org.apache.pdfbox.exceptions.COSVisitorException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
    at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1354)
    at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:217)
    at org.apache.pdfbox.cos.COSObject.accept(COSObject.java:206)
    at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:525)
    at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:435)
    at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1122)
    at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:552)
    at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1501)
    at org.apache.pdfbox.pdmodel.PDDocument.saveIncremental(PDDocument.java:1369)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at org.apache.pdfbox.io.RandomAccessBuffer.seek(RandomAccessBuffer.java:84)
    at org.apache.pdfbox.io.RandomAccessFileInputStream.read(RandomAccessFileInputStream.java:96)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
    at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1337)
    ... 12 more

什么时候发生这个异常?

源代码:

  public void sign(File inputDocument, File outputDocument, DigitalSigningToken token,
                DigitalSignSettings settings) {

            byte[] buffer = new byte[8 * 1024];

            FileInputStream fis = new FileInputStream(inputDocument);
            FileOutputStream fos = new FileOutputStream(outputDocument);

            int c;
            while ((c = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, c);
            }
            fis.close();
            fis = new FileInputStream(outputDocument);


            PDDocument doc = PDDocument.load(inputDocument);

            create signature dictionary
            PDSignature signature = new PDSignature();
            signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); 
            signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED);
            signature.setName(settings.getSignerName());
            signature.setLocation(settings.getSignerLocation());
            signature.setReason(settings.getSignatureReason());
            SignatureOptions options = new SignatureOptions();
            options.setPage(settings.getPage());
            options.setPreferedSignatureSize(settings.getPreferredSize());
            options.setVisualSignature(settings.getSignatureImage());


            // TokenSignature  implements org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface
            doc.addSignature(signature, new TokenSignatureInterface(token, profile), options);

            doc.saveIncremental(fis, fos);
            }

doc.saveIncremental 的异常(不是每次

在签名方法之前,如果我有System.gc(),一切正常。我不明白为什么。在签名方法之前,我创建了可见的签名:

    DigitalSignSettings settings = new DigitalSignSettings();
    settings.setSignerName("");
    settings.setSignerLocation("");
    settings.setSignatureReason("");
    settings.setPreferredSize(0);
    settings.setPage(1);
    settings.setVisualSignEnabled(true);

    FileInputStream fin = new FileInputStream("c:\\sig.jpg");
    PDFBuilder builder = new VisibleSignaturePDFBuilder();
// builder pattern, which creates pdf vith visible signature
    PDFCraator creator = new PDFCraator(builder);

    VisibleSignatureConfig properties = new VisibleSignatureConfig(originalDocument.getAbsolutePath(), fin, 1);
    ByteArrayInputStream template = creator.buildPDF(properties);


    System.gc(); 


    settings.setSignatureImage(template);
    PDFSigner signer = new PDFSigner();
    signer.signDocument(originalDocument, outputDocument, token,  settings);

我还发现,在 Builder 中,如果我注释一种方法,则不会发生此异常。就是这样/ PDJpeg 导致了这个......

@Override
public void createSignatureImage(PDDocument template, InputStream inputStream) throws IOException {
    PDJpeg img = new PDJpeg(template, inputStream);
    pdfStructure.setJpedImage(img);
    logger.info("Visible Signature Image has been created");
    inputStream.close();

}

或者代替 System.gc(),如果我创建 for(int i=0; i<10000000; i++){} 这也有效!非常非常非常混乱。哦..我不知道发生了什么...这对我来说很困惑...

4

1 回答 1

2

PDFBox 中实际上存在一个错误。我也遇到了这个问题,并在这个论坛帖子中找到了一些解释:

保存文档时出现 IndexOutOfBoundsException(随机)

我发现这是对帖子问题的最佳描述:

“问题是对 scratchFile 的引用不止一个。COSDocument 假定它对该 scratchFile 具有排他性并将关闭它。有时一个(单个)scratchFile 被多个对象使用。作为创建ScratchFile 超出范围并获得 GC 的 finalize() 调用 close() 在 scratchFile - 但可能有另一个引用它。如果 COSDocument 将它的 scratchFile 保持为私有(删除 getter),这将不再发生并使在 finalize safe 期间关闭。我们看到的是,此堆栈跟踪是在拥有实例 COSDocument 已被 GC'd 后调用的对 scratchFile 的第二次引用的结果。COSDocument 中的 getter 将不会永远不会在崩溃发生时在最初创建它的 COSDocument 实例上调用,因为该 COSDocument 实例已经被 GC - 可能很久以前!”

作者已经分支了一个解决方案版本,但要注意内存泄漏等。

希望这可以帮助!

于 2013-11-11T23:21:00.957 回答