views:

1753

answers:

3

I use this test to convert txt to pdf :

package convert.pdf;

//getResourceAsStream(String name) : Returns an input stream for reading the specified resource.
//toByteArray : Get the contents of an InputStream as a byte[].

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;

import convert.pdf.txt.TextConversion;

public class TestConversion {

  private static byte[] readFilesInBytes(String file) throws IOException {
      return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
  }

  private static void writeFilesInBytes(byte[] file, String name) throws IOException {
      IOUtils.write(file, new FileOutputStream(name));
  }

  //just change the extensions and test conversions
  public static void main(String args[]) throws IOException {
      ConversionToPDF algorithm = new TextConversion();
      byte[] file = readFilesInBytes("/convert/pdf/text.txt");
      byte[] pdf = algorithm.convertDocument(file);
      writeFilesInBytes(pdf, "text.pdf");
  }

}

Problem:

Exception in thread "main" java.lang.NullPointerException
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
    at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:218)
    at convert.pdf.TestConversion.readFilesInBytes(TestConversion.java:17)
    at convert.pdf.TestConversion.main(TestConversion.java:28)

I use the debugger, and the problem seems to be located here :

  private static byte[] readFilesInBytes(String file) throws IOException {
      return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
  }

What is my problem?

A: 

Are you checking to see if the file exists before you pass it to readFilesInBytes()? Note that Class.getResourceAsStream() returns null if the file cannot be found. You probably want to do:

private static byte[] readFilesInBytes(String file) throws IOException {
  File testFile = new File(file);
  if (!testFile.exists()) {
      throw new FileNotFoundException("File " + file + " does not exist");
  }
  return IOUtils.toByteArray(TestConversion.class.getResourceAsStream(file));
}

or better yet:

private static byte[] readFilesInBytes(String file) throws IOException {
  InputStream stream = TestConversion.class.getResourceAsStream(file);
  if (stream == null) {
      throw new FileNotFoundException("readFilesInBytes: File " + file
                                      + " does not exist");
  }
  return IOUtils.toByteArray(stream);
}
Eddie
+2  A: 

Sounds like the resource probably doesn't exist with that name.

Are you aware that Class.getResourceAsStream() finds a resource relative to that class's package, whereas ClassLoader.getResourceAsStream() doesn't? You can use a leading forward slash in Class.getResourceAsStream() to mimic this, so

Foo.class.getResourceAsStream("/bar.png")

is roughly equivalent to

Foo.class.getClassLoader().getResourceAsStream("bar.png")

Is this actually a file (i.e. a specific file on the normal file system) that you're trying to load? If so, using FileInputStream would be a better bet. Use Class.getResourceAsStream() if it's a resource bundled in a jar file or in the classpath in some other way; use FileInputStream if it's an arbitrary file which could be anywhere in the file system.

EDIT: Another thing to be careful of, which has caused me problems before now - if this has worked on your dev box which happens to be Windows, and is now failing on a production server which happens to be Unix, check the case of the filename. The fact that different file systems handle case-sensitivity differently can be a pain...

Jon Skeet
A: 

This class reads a TXT file in the classpath and uses TextConversion to convert to PDF, then save the pdf in the file system.

Here TextConversion code :

package convert.pdf.txt;
//Conversion to PDF from text using iText.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import convert.pdf.ConversionToPDF;
import convert.pdf.ConvertDocumentException;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;

public class TextConversion implements ConversionToPDF {

    public byte[] convertDocument(byte[] documents) throws ConvertDocumentException {
     try {
      return this.convertInternal(documents);
     } catch (DocumentException e) {
      throw new ConvertDocumentException(e);
     } catch (IOException e) {
      throw new ConvertDocumentException(e);
     }
    }

    private byte[] convertInternal(byte[] documents) throws DocumentException, IOException {
     Document document = new Document();

        ByteArrayOutputStream pdfResultBytes = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, pdfResultBytes);

        document.open();

        BufferedReader reader = new BufferedReader( new InputStreamReader( new ByteArrayInputStream(documents) ) );

        String line = "";
        while ((line = reader.readLine()) != null) {
            if ("".equals(line.trim())) {
             line = "\n"; //white line
            }
            Font fonteDefault = new Font(Font.COURIER, 10);
      Paragraph paragraph = new Paragraph(line, fonteDefault);
      document.add(paragraph);
        }

        reader.close();

        document.close();

        return pdfResultBytes.toByteArray();
    }
}

And here the code to ConversionToPDF :

package convert.pdf;
// Interface implemented by the conversion algorithms.
public interface ConversionToPDF {

    public byte[] convertDocument(byte[] documentToConvert) throws ConvertDocumentException;
    }

I think the problem come from my file system (devbox on windows and server is Unix). I will try to modify my classpath.