How can I check if a JAR file is valid?

classpath, jakarta-ee, jar, java

Solution

A way to programmatically detect an invalid jar file is to use `java.util.ZipFile`.

public static void main(String[] args) {
    if(args.length < 1) {
        System.err.println("need jar file");
        return;
    }
    
    String pathname = args[0];
    try {
        ZipFile file = new ZipFile(new File(pathname));
        Enumeration<? extends ZipEntry> e = file.entries();
        while(e.hasMoreElements()) {
            ZipEntry entry = e.nextElement();
            System.out.println(entry.getName());
        }
    } catch(Exception ex) {
        ex.printStackTrace();
    }
}

If the jar file is invalid, a `ZipException` will be thrown when instantiating the `ZipFile` object.

Problem

My webapp allows a user to upload a JAR file. However, after the jar file is uploaded, it is corrupted. I have verified this by comparing the MD5 checksums before and after uploading the file (winmd5free). The uploaded jar file is almost identical to the original: - The file size compared to the original is similar (at the KB level) - I can open the uploaded jar file using an unzipping program and view it's contents (resources and class files), and everything is the same compared to the original file When I open up the uploaded jar file (using Notepad++), I did notice that the binary contents are different from the original. Also, when I used `JarInputStream` to read the JAR entries, there were no entries. ``` JarInputStream is = new JarInputStream(new FileInputStream(new File("uploaded.jar"))); JarEntry entry = null; while(null != (entry = is.getNextJarEntry())) { System.out.println(entry.getName()); } ``` Furthermore, when I double click on the jar (Windows), I get the following message. Error: Invalid or corrupt jarfile My questions are: - Is there a way to programmatically check if a jar file is valid? I would have expected `JarInputStream` to detect this right away, but it shows no problems at all - When I double click on the jar file, in windows, is it java.exe that is giving me the "invalid or corrupt JAR file" message? - How come when an invalid jar file is passed in as part of the classpath, no error/exception is thrown? For example, by running the `java -cp uploaded.jar;libs\* com.some.class.Test` command? This question is irrelevant from jar signing and/or checking the signature of a JAR file. It is simply checking if a file (uploaded or not) is a valid JAR file (not necessarily if the jar's class files are valid, as there is another SO post on this issue already). My results for running `jar -tvf uploaded.jar`: ``` java.util.zip.ZipException: error in opening zip file at java.util.zip.ZipFile.open(Native Method) at java.util.zip.ZipFile.<init>(ZipFile.java:127) at java.util.zip.ZipFile.<init>(ZipFile.java:88) at sun.tools.jar.Main.list(Main.java:977) at sun.tools.jar.Main.run(Main.java:222) at sun.tools.jar.Main.main(Main.java:1147) ```

Original source