I've been debugging some jar-update snippets and I came across a zip/unzip combination that should be reversing the other, but when I tried it on a jar it failed even though all the files are present. Can anyone figure out where this is going wrong?
SSCCE (no need to compile): Download here!
package jarsscce;
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
public class JarSSCCE {
public static void main(String[] args) throws IOException {
File testJar = new File("test.jar");
File testDir = new File("test");
File jarPack = new File("packed_test.jar");
unpack(testJar, testDir);
jar(testDir, jarPack);
}
public static void jar(File directory, File zip) throws IOException {
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(zip))) {
jar(directory, directory, jos);
}
}
private static void jar(File directory, File base, JarOutputStream jos) throws IOException {
File[] files = directory.listFiles();
byte[] buffer = new byte[1 << 12];
if (files.length == 0) {
JarEntry entry = new JarEntry(directory.getPath().substring(base.getPath().length() + 1) + File.separator);
jos.putNextEntry(entry);
} else {
for (int i = 0, n = files.length; i < n; i++) {
if (files[i].isDirectory()) {
jar(files[i], base, jos);
} else {
try (FileInputStream in = new FileInputStream(files[i])) {
JarEntry entry = new JarEntry(files[i].getPath().substring(base.getPath().length() + 1));
jos.putNextEntry(entry);
int read;
while ((read = in.read(buffer, 0, buffer.length)) != -1) {
jos.write(buffer, 0, read);
}
jos.closeEntry();
}
}
}
}
}
public static void unpack(File zip, File extractTo) throws IOException {
try (ZipFile archive = new ZipFile(zip)) {
Enumeration e = archive.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
File file = new File(extractTo, entry.getName());
if (entry.isDirectory() && !file.exists()) {
file.mkdirs();
} else {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (InputStream in = archive.getInputStream(entry)) {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
byte[] buffer = new byte[1 << 13];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
}
}
}
}
}
}
EDIT: Looking at the archive information via Winrar, I can see that the test.jar created by Netbeans is not compressed at all, and the one created by the program is. Also the "Host OS" and "Version to extract" values are different. Though I can't see how any of that would be significant.