views:

234

answers:

1

Hi,

This is the situation. I need to add PDF generation to a program that already has PNG generation. Initially the 2 classes involved are : ActionUsuels From where the constructor of CaptureImage3D is called.

When I added the PDF generation I added a method at the CaptureImage3D class. Before adding the PDF generation, the PNG generation worked correctly. But now when I try to do the PNG generation, I get a : NoClassDefFoundError: com/lowagie/text/DocumentException.

I know it means that the class : DocumentException (from the itext jar) can't be read from the classpath but :

  1. The PDF generation method is NEVER called.
  2. The exception is generated before entering the constructor of CaptureImage3D.
  3. Consider the following PDF generation method:

Code:

  public void captureImagePDF(File imageFile)
  {

        System.out.println("Pdf appelé");

        // Dimension (en pixels) de l'image a sauvegarder dans le fichier
        Dimension dim = new Dimension(512, 512);

        // On recupere l'image (pixmap) rendue par le canvas 3D offscreen
        BufferedImage myBufferedImage = offScreenCanvas.getOffScreenImage(dim);

        // On recupere le contexte graphique de l'image finale de sortie
        Graphics2D gc = myBufferedImage.createGraphics();

        gc.drawImage(myBufferedImage, 0, 0, null);

        Document myPDF = new Document(PageSize.A4, 50, 50, 50, 50);

        PdfWriter myWriter = null;

        try 
        {
            myWriter = PdfWriter.getInstance(myPDF, new FileOutputStream(imageFile));
        } 


        catch (FileNotFoundException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        catch (DocumentException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        myPDF.open();
        PdfContentByte cb = myWriter.getDirectContent();
        cb.saveState();
        Image image = null;

        try {
            image = Image.getInstance(myBufferedImage,null);
        } 

        catch (BadElementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
                cb.addImage(image);
        } 
        catch (DocumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }


  }

When I comment all the try/catch blocs, everything works fine !!!

I repeat again: captureImagePDF is never called. And even the constructor of CaptureImage3D is never accessed. (it should be, but the exception is raised before). And yes, I have itext in the classpath.

I find it weird the fact that a piece of code, that is never called anywhere, causes the apparition of the exception!

Don't hesitate to ask for clarifications!

Any idea?

Thank you

+2  A: 

The fact that you have a catch for DocumentException means that the loader has to load the class, so that the system can catch it. :-)

If you want to avoid having to have the iText jar in your classpath, catch something higher up, or (like you said) don't catch at all. :-P

Chris Jester-Young
This is correct. The classloader will load all classes that are "statically" required by the executing code.
Romain
But I imported the specific class: import com.lowagie.text.DocumentException;And I've put the itext jar in the Java Build Path -> LibrariesWhat's wrong ?
Amokrane
@Amokrane: The build path lists jars for building. You also need the same jar in the classpath, so that it's available at run time. :-)
Chris Jester-Young
I used the following compilation directive : javac -d ./class -classpath .;./Java3D/lib/j3dcore.jar;./Java3D/j3dutils.jar;./Java3D/lib/vecmath.jar;./librairies/itext-1.3.6.jar ./src/*.java So as you can see, the jar is in the classpath isn't it ? (itext-1.3.6.jar)
Amokrane
@Amokrane: You also have to specify it in the classpath when you _run_ your program. Specifying the classpath when you compile it does not "bake" it into the program, sorry. :-(
Chris Jester-Young
Oh man, yes sure ! Sorry for misunderstanding you, I'm such a looser ^^. It's working now that I have added the jar in the classpath at run time. Thank you!
Amokrane