My project has multiple images and one pdf file. Project's JAR needs to be used on various PCs having Linux or Windows in our different offices across multiple cities. That's why I want all the resources to be part of the same single JAR file for easy and error-free portability.
I'm already successfully accessing my images/icons as resources using:
public static final ImageIcon CopyIcon = new ImageIcon(Global.class.getResource("/cct/resources/copy.png"));
But when i access the User Manual (pdf) file using similar code:
File userManual = new File(Global.class.getResource("/cct/resources/manual.pdf").toURI());
Desktop.getDesktop().open(userManual);
...the user manual opens fine when run from within eclipse but no response when accessed from jar file created using
Export => Runnable JAR file => 'Extract/Package required libraries into generated JAR'
option. All other options work seamlessly.
I've tried many solutions found here on SO, but none works because most of them are for other file types e.g. txt or excel or images.
Thanks to @howlger's mentioned answer, I modified my code as follows to make my pdf accessible both from eclipse and JAR.
public static void openUserManual() {
File userManual;
try {
userManual = new File(Global.class.getResource("/cct/resources/manual.pdf").toURI());
Desktop.getDesktop().open(userManual); // works when run from eclipse
}
catch (Exception ex) {
try {
userManual = getResourceAsFile(Global.class.getResource("/cct/resources/manual.pdf").getPath());
if (userManual != null)
Desktop.getDesktop().open(userManual); // works when run from JAR
else
JOptionPane.showMessageDialog(null, "User Manual couldn't be accessed.");
}
catch (Exception exp) { exp.printStackTrace(); }
}
}
private static File getResourceAsFile(String resourcePath) {
try (InputStream in = Global.class.getResourceAsStream(resourcePath)) {
if (in == null)
return null;
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1)
out.write(buffer, 0, bytesRead);
}
return tempFile;
} catch (IOException exp) { exp.printStackTrace(); return null; }
}