I have a compressed file in the Resources folder which is decompressed in the folder where the program is run for the first time. If the program starts from Eclipse, the file is found and decompressed without problems. When I export the program in a jar file, and run the program with:
java -jar JRS2020-31.jar
the output is:
java.lang.RuntimeException: Error unzipping file initialData/compressed.zip
at InterpreteSQL.Main.unzip(Main.java:111)
at InterpreteSQL.Main.CreateInitialDirectoryIfNotFound(Main.java:77)
at InterpreteSQL.Main.main(Main.java:60)
Caused by: java.io.FileNotFoundException: file:/Users/XXX/JRS2020-31.jar!/initialData/compressed.zip (No such file or directory)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:219)
at java.util.zip.ZipFile.<init>(ZipFile.java:149)
at java.util.zip.ZipFile.<init>(ZipFile.java:120)
at InterpreteSQL.Main.unzip(Main.java:88)
... 2 more
Note that other files in resources (help html files) are opened regularly in the program.
This is the code that opens the file:
public static void unzip(String zipFilePath, String unzipDir) throws Exception {
try{
ZipFile zipFile = new ZipFile(Main.class.getClassLoader().getResource(zipFilePath).getFile());
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
...
and it is called with:
unzip("initialData/compressed.zip", "JRS_directory");
Note that the program is run in the home folder, and that it can create directories and files.
Any idea about the problem? Thank you very much.
You'reusing getResources wrong, in two ways.
Don't use ZipFile
; use ZipInputStream
which has very similar API. Then use getResourceAsStream
.
Main.class.getResource()
. Avoid the classloader intermediate. It is both a pointless method call, and in rare cases will break (in certain contexts, a class's classloader is null, causing a nullpointerexception). Note that this form means the string you pass in is relative to the class location. If you don't want that, add a leading slash.While you're at it, these are resources that must be closed, so let's use the try-with-resources construct to ensure this is done properly even in the face of exceptions.
Putting this together:
try (InputStream raw = Main.class.getResourceAsStream("/" + zipFilePath);
ZipInputStream zip = new ZipInputStream(raw)) {
for (ZipEntry entry; (entry = zip.getNextEntry()) != null; ) {
// do something with entry here
}
}