0

I am trying to open a pdf file in my java code. The pdf (named "test.pdf") is saved in packageA. The class (ClassB) trying to open the file is in packageB. I am using the following code:

try {
    File pdfFile = new File(ClassB.class.getResource("/packageA/test.pdf").getPath());
    if (pdfFile.exists()) {
        if (Desktop.isDesktopSupported()) {
            Desktop.getDesktop().open(pdfFile);
        }
    }
    else {
        //error
}
catch (Exception e) {
    //error
}

This works when I run it in eclipse but when I export the program as an executable jar it doesnt work. I get a file not found. I did some research and tried using the following which also didnt work outside eclipse:

ClassLoader cl = this.getClass().getClassLoader();
File pdfFile = new File(cl.getResource("packageA/test.pdf").getFile());
user3245747
  • 805
  • 2
  • 17
  • 30
  • I would recommend trying InputStream resourceStream = loader.getResourceAsStream("filename"). This link explains why so. http://stackoverflow.com/questions/2308188/getresourceasstream-vs-fileinputstream – poodle Dec 22 '14 at 20:28
  • but how can I open the file once I get it? the Desktop.getDesktop().open() method takes a file and not a stream. – user3245747 Dec 22 '14 at 20:37

1 Answers1

0

As explained in this other Stack Overflow question

The URI is not hierarchical occurs because the URI for a resource within a jar file is most likely going to look like something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.

Instead get the file bytes as an InputStream

InputStream pdf = ClassB.class.getResourceAsStream("packageA/test.pdf");

This should work both in eclipse (which is still reading the files off of the filesytem) and from the executable jar

EDIT

Since you need to use a File no matter what, the only sure way to get a file is to make a temp file:

            // Copy file
            File tmpFile = File.createTempFile(...);
            tmpFile.deleteOnExit();
            try(OutputStream outputStream = new FileOutputStream(tmpFile);
                InputStream pdf = ClassB.class.getResourceAsStream("packageA/test.pdf"); ){

                byte[] buffer = new byte[1024];
                int length;
                while ((length = pdf.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
            }//autoClose
            //now tmpFile is the pdf
             Desktop.getDesktop().open(tmpFile);
Community
  • 1
  • 1
dkatzel
  • 31,188
  • 3
  • 63
  • 67
  • Yes this does work but how can I then open the file? The whole point of the operation is to allow the user to open the pdf through his/her native pdf reader. – user3245747 Dec 22 '14 at 20:36