This is one of those error messages that comes up a lot, but none of the question/answers address this particular situation.
java.util.zip.*
functions to create the runnable jar, it does
not work.Why would one file work, and the other, seemingly identical file not work?
Here's a snip of the code that I'm using. Not the full implementation, just the interesting bit:
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
for (int i = 0; i < fileList.length; i++) {
InputStream in = new FileInputStream(fileList[i]);
String absoluteFileNameString = fileList[i].getAbsolutePath();
if (baseDirectory != null && baseDirectory.length() > 0 && absoluteFileNameString.length() > (baseDirectory.length() + 1) ) {
absoluteFileNameString = absoluteFileNameString.substring(baseDirectory.length() + 1);
}
out.putNextEntry(new ZipEntry(absoluteFileNameString));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
in.close();
}
out.close();
Here is the output showing that one works and the other doesn't:
C:\Users\Owner\git\runnablejarbuilder\RunnableJarBuilder>java -jar RunnableJarBuilder.zip
Error: Could not find or load main class com.rjb.test.HelloRun
Caused by: java.lang.ClassNotFoundException: com.rjb.test.HelloRun
C:\Users\Owner\git\runnablejarbuilder\RunnableJarBuilder>java -jar RunnableJarBuilderIDE.zip
Hello Runnable Jar!
Below is a screen shot (the only way to capture what Windows explorer was telling me: the files were exactly duplicates of each other):
After analyzing the zip files using zipdump, I realized my code was using backslashes (\
) as a path separator, but ZipEntry
expected a forward slash (/
). This was my non-working file:
C:\Users\Owner\git\runnablejarbuilder\RunnableJarBuilder\zipdump>C:\Users\Owner\AppData\Local\Programs\Python\Python38-32\python.exe zipdump.py RunnableJarBuilder.zip
75 ( 97.3%) 2024-11-18 12:27:10 106e3e9c [NOLFH] META-INF/MANIFEST.MF
7831 ( 48.9%) 2024-11-18 12:27:10 a30be143 [NOLFH] com\rjb\test\BuildJarFromClassFiles.class
4601 ( 53.4%) 2024-11-18 12:27:10 0742ac06 [NOLFH] com\rjb\test\ClasspathReader.class
561 ( 62.2%) 2024-11-18 12:27:10 d38480b3 [NOLFH] com\rjb\test\HelloRun.class
6525 ( 50.6%) 2024-11-18 12:27:10 364411d0 [NOLFH] com\rjb\test\JarUpdater.class
And this was the working one, which the IDE created:
C:\Users\Owner\git\runnablejarbuilder\RunnableJarBuilder\zipdump>C:\Users\Owner\AppData\Local\Programs\Python\Python38-32\python.exe zipdump.py RunnableJarBuilderIDE.zip
75 ( 97.3%) 2024-11-18 12:25:54 106e3e9c [NOLFH] META-INF/MANIFEST.MF
4601 ( 53.4%) 2024-11-18 10:44:42 0742ac06 [NOLFH] com/rjb/test/ClasspathReader.class
7831 ( 48.9%) 2024-11-18 12:23:00 a30be143 [NOLFH] com/rjb/test/BuildJarFromClassFiles.class
561 ( 62.2%) 2024-11-18 09:02:48 d38480b3 [NOLFH] com/rjb/test/HelloRun.class
6525 ( 50.6%) 2024-11-18 09:46:12 364411d0 [NOLFH] com/rjb/test/JarUpdater.class
I fixed the problem by replacing all the backslashes with forward slashes in the path name:
//REPLACE THIS LINE
//String absoluteFileNameString = fileList[i].getAbsolutePath();
//WITH THIS LINE - Never use backslashes in zip file entries!!
//String absoluteFileNameString = fileList[i].getAbsolutePath().replace("\\","/");
// or better, suggested by DuncG
String absoluteFileNameString = fileList[i].getAbsolutePath().replace(File.separatorChar,"/");
This might come up on Windows especially, and may be less of a problem on Linux.