How to load a PDF from a .jar File? - java

I have made a Swing application and will include a file, help.pdf in the .jar file. When the user selects Help->User Guide from a JMenuItem, it should load the file in the default PDF viewer on the system.
I have the code to load the PDF,
private void openHelp() {
try {
java.net.URL helpFile = getClass().getClassLoader().getResource("help.pdf");
File pdfFile = new File(helpFile.getPath());
if (pdfFile.exists()) {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(pdfFile);
} else {
System.out.println("Awt Desktop is not supported!");
}
} else {
System.out.println("File does not exist!");
}
System.out.println("Done");
} catch (Exception ex) {
ex.printStackTrace();
}
}
This works in the eclipse IDE, however, when I pack it into a jar for other people it no longer works.
How do I fix this problem?

The problem is that a File cannot name a component of a JAR file. What you need to do is to copy the resource from the JAR file into a temporary file in the filesystem, and open using the File for the temporary file.

File names in a .jar file are case sensitive. In your text you write Help.pdf but in the code you use help.pdf. The upper/lowercase in the Java code must match the case of the file, even if you are using a system where the filesystem is not case sensitive.
Try
getResource("Help.pdf");
instead (assuming the filename in your posting text is correct)

I think you have to retrieve the location of the jar, open it and load the pdf file from within your application. The .jar file is just a zipped archive, which can be read with java easily...

Related

Netbeans- reach resources folder

I know that this question it is similar to this one but it is different. I am trying to open a pdf file that it is in the resources folder of netbeans.
Right now I am in the EventoService.java and I have created a file object to open the pdf file (justificante.pdf) in "Other Resources" folder. I have tried to reach the pdf file like in the link before but it doesn't work because of the constructor. How can I reach it? Thank you in advance.
if (Desktop.isDesktopSupported()) {
try {
File myFile = new File(getClass().getClassLoader().getResource("resources/justificante.pdf"));
Desktop.getDesktop().open(myFile);
} catch (IOException ex) {
// no application registered for PDFs
}
}

JavaFX:Editable Configuration Files After Packaging

I've a JavaFX application that I packaged it using antBuild to build a single installer .exe file, my app have some configuration files that was placed in the root of the project this way i load them from the root of the project in order to they can be place beside the .jar file and could be changable:
try {
File base = null;
try {
base = new File(MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.getParentFile();
} catch (URISyntaxException e) {
System.exit(0);
}
try {
File configFile = new File(base, "config.properties");
}
so after packaging the app even if I put the files manually in the same place with jar file, again the app can not recognize them and put into error.
So what is the proper way to store and where to store some sort of config files and how to add them to the installer to put it to right place during installation?
If your application is bundled as a jar file, then MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI() will return a jar: scheme URI. The constructor for File taking a URI assumes it gets a file: scheme URI, which is why you are getting an error here. (Basically, if your application is bundled as a jar file, the resource config.properties is not a file at all, its an entry in an archive file.) There's basically no (reliable) way to update the contents of the jar file bundling the application.
The way I usually approach this is to bundle the default configuration file into the jar file, and to define a path on the user file system that is used to store the editable config file. Usually this will be relative to the user's home directory:
Path configLocation = Paths.get(System.getProperty("user.home"), ".applicationName", "config.properties");
or something similar.
Then at startup you can do:
if (! Files.exists(configLocation)) {
// create directory if needed
if (! Files.exists(configLocation.getParent())) {
Files.createDirectory(configLocation.getParent());
}
// extract default config from jar and copy to config location:
try (
BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/config.properties")));
BufferedWriter out = Files.newBufferedWriter(configLocation);) {
in.lines().forEach(line -> {
out.append(line);
out.newLine();
});
} catch (IOException exc) {
// handle exception, e.g. log and warn user config could not be created
}
}
Properties config = new Properties();
try (BufferedReader in = Files.newBufferedReader(configLocation)) {
config.load(in);
} catch (IOException exc) {
// handle exception...
}
So this checks to see if the config file already exists. If not, it extracts the default config from the jar file and copies its content to the defined location. Then it loads the config from the defined location. Thus the first time the user runs the application, it uses the default configuration. After that, the user can edit the config file and subsequently it will use the edited version. You can of course create a UI to modify the contents if you like. One bonus of this is that if the user does something to make the config unreadable, they can simply delete it and the default will be used again.
Obviously this can be bullet-proofed against exceptions a little better (e.g. handle case where the directory is unwritable for some reason, make the config file location user-definable, etc) but that's the basic structure I use in these scenarios.

How can I delete a downloaded file using Selenium RemoteWebDriver?

I am writing a test to check that a file can be downloaded from a particular web page and I want it to be able to run both locally and remotely (i.e. on a node via Selenium grid). Before anyone links me to the 'do you really need to download the file?' article, I have already managed to download and check the file, I just need a way of deleting it after the test has completed. Just calling File.delete(); or similar will only work locally (as far as I'm aware) so I can't use that to delete the file from the node machine. I'm aware of the class org.openqa.selenium.io.TemporaryFileSystem however I can't find any instructions for how to use it.
Can anyone offer a better solution than 'just run a script on the node machine to delete the file'? Thanks!
You can make the download folder shared. \youruser\downloads after that you can pass this path to the File.Delete(); and it will delete the desired files.
Cleanup of downloaded files within session of Grid Node feature is planned:
https://github.com/SeleniumHQ/selenium/issues/11457
https://github.com/SeleniumHQ/selenium/issues/11657
This Worked for me
try
{
if ((new File("Path")).delete()) {
System.out.println("Pass");
} else {
System.out.println("Failed");
}
} catch (Exception ex) {
ex.printStackTrace();
}
----------simply use this code for delete file in any folder-------------------
File file = new File("C:\\Users\\Updoer\\Downloads\\Inspections.pdf");
if(file.delete())
System.out.println("file deleted");
The Below Code will sequentially delete all the files from folder
File path = new File("Path of Folder");
File[] files = path.listFiles();
for (File file : files) {
System.out.println("Deleted filename :"+ file.getName());
file.delete();
}

Java: Run/Open/Edit any file

Using Java program I need to run/open/edit any file. This should have similar effect of double clicking file in File Explorer and OS will execute file if it an executable OR open/edit it in it's respective registered program.
I have tried the Runtime.exec() method (See down there) but that method only runs executable files. I need mine to run any file. This includes text files, audio files, pictures, anything.
I have tried the following:
Runtime.getRuntime().exec("README.txt");
Have you consider trying to use the java.awt.Desktop class?
For example...
if (Desktop.isDesktopSupported()) {
try {
if (Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
Desktop.getDesktop().edit(new File("Readme.txt"));
}
// or...
if (Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
Desktop.getDesktop().open(new File("Readme.txt"));
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
This will attempt to open/edit the file in the OS specified editor for the given file

How can I return the file path using the JNLP file chooser

Hi I am trying to get the returned file path by my JNLP file chooser. Here's my code.
I don't know how and where to get the file path. is it from fileContents? fileConents.getfilepath something like that?
try {
if (fileOpenService==null) {
fileOpenService = (FileOpenService)ServiceManager.
lookup("javax.jnlp.FileOpenService");
}
fileContents = fileOpenService.openFileDialog(path, xtns);
} catch(UnavailableServiceException use) {
use.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
Thanks in advance!
According to http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html
You can call other methods on the File object, such as
getPath, isDirectory, or exists to obtain information about the file.
You can also call other methods such as delete and rename to change
the file in some way. Of course, you might also want to open or save
the file by using one of the reader or writer classes provided by the
Java platform. See Basic I/O for information about using readers and
writers to read and write data to the file system.
It is for security reasons that a FileContents will not return a path. The JRE asked the user if our app. could access the content of that file, not it's path.
It is a bit like the brower/HTML based file upload field. Some browsers provide the entire path, while more typically it is just the content/name.

Categories