Search code examples
javajakarta-eejarclasspath

How can I check if a JAR file is valid?


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)

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.