简体   繁体   中英

PDFBox error: “org.apache.pdfbox.rendering.PDFRenderer not found” when it is present

I am writing a plugin for Bitbucket Server, in which I have to deal with rendering PDFs to images. I use PDFBox for this purpose. I have a pdfToPng method that will be called to do the processing and I have modified the PDF renderer similarly to what the Apache examples suggest.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.rendering.PageDrawerParameters;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class PDFProcessor {

    private static Logger logger = LoggerFactory.getLogger(PDFProcessor.class);

    private static int _colorMode;

    /**
     * Convert a page of a PDF document into a colored PNG
     * @param color color to use, 0 - black, 1- red
     * @param fileName output file
     * @param pdfFile PDF to process
     * @throws IOException
     */
    public static void pdfToPng(int color, String fileName, File pdfFile) throws IOException{
        _colorMode = color;
        try (PDDocument pdfDoc = PDDocument.load(pdfFile)){
            logger.info("Begin PDF to PNG render for " + fileName);
            PDFRenderer renderer = new CustomPdfRenderer(pdfDoc);
            BufferedImage image = renderer.renderImageWithDPI(0,600);
            logger.info("Making PNG transparent...");
            BufferedImage transparentImage = ImageProcessor.makeTransparent(image,new Color(image.getRGB(0,0)));
            ImageIO.write(transparentImage, "PNG",new File(fileName+".png"));
            logger.info("Image processed successfully, writing to " + fileName + ".png");
        }
    }

    private static class CustomPdfRenderer extends PDFRenderer{
        CustomPdfRenderer(PDDocument document){
            super(document);
        }

        @Override
        protected PageDrawer createPageDrawer(PageDrawerParameters params) throws IOException{
            return new CustomPageDrawer(params);
        }
    }

    private static class CustomPageDrawer extends PageDrawer{
        CustomPageDrawer(PageDrawerParameters params) throws IOException{
            super(params);
        }

        @Override
        protected Paint getPaint(PDColor color) throws IOException{
            if ((color.toRGB() == (Color.BLACK.getRGB() & 0x00FFFFFF)) && (_colorMode == 1)){
                return Color.RED;
            }
            return super.getPaint(color);
        }
    }
}

The project is built using Maven, as this is when BitBucket uses for the plugin development. However, when the method is actually called, I get a ClassNotFound exceptioni stating:

[INFO] Caused by: java.lang.NoClassDefFoundError: org/apache/pdfbox/rendering/PDFRenderer
[INFO]  at com.my-plugin.DiffManager.prepareDiff(DiffManager.java:99)
[INFO]  at com.my-plugin.DiffManager.doGet(DiffManager.java:67)
[INFO]  at com.my-plugin.DiffManager.doPost(DiffManager.java:84)
[INFO]  ... 33 common frames omitted
[INFO] Caused by: java.lang.ClassNotFoundException: org.apache.pdfbox.rendering.PDFRenderer not found by com.my-plugin.integrationPlugin [219]
[INFO]  at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
[INFO]  ... 36 common frames omitted

As you can see, I have imported the PDFRenderer class. My pom.xml also contains the correct dependency definition:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.14</version>
    <scope>provided</scope>
</dependency>

Why can't Java find the PDFRenderer class? The other dependencies that are declared in this way never has this problem.

You are using the dependency of pdfbox with <scope>provided</scope> . Who do you expect to provide this dependency when it is needed? An application container like Tomcat?

I suggest that you delete the scope line, so the dependency will be implicitly compile scope, which should solve the problem for you.

Please consult also the Maven scope docs which say:

  • compile – This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project.

  • provided – This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM