Search code examples
javajarchecksumcrc

Does a .JAR file not perform a checksum check when executed?


I was testing something along the lines of:
- Alter the content of a JAR file (via Notepad++)
- Save and run it

As JAR files are basically just ZIP archives, I assumed that before the JVM actually runs the JAR file, the checksums are being verified. But that was not the case, the JAR file was executed and an exception was thrown, that something was missing.

When extracting with 7zip for example, a CRC error is reported. I expected the same behavior when running it.

Am I missing something? Or is there actually no checksum check performed before/while running a JAR file?


Solution

  • The short answer:

    As long as you do not use an old Java version <= 7 that misses a fix for this bug and as long as you do not use a custom ClassLoader the CRC of each zip entry within a JAR file is verified when a JAR is loaded from classpath.

    The long answer (by example for Java 8, I'm not aware of any known regression bugs in newer Java versions):

    Java's URLClassLoader (default system classloader in Java 8) uses class sun.net/www/protocol/jar/JarURLConnection to read JAR files from URLs.

    This class uses sun/net/www/protocol/jar/URLJarFile which is a sub class of java/util/zip/ZipFile. This class calls the read method of a java/util/zip/ZipInputStream to read zip entries.

    The ZipInputStream class verifies CRC for uncompressed Zip entries here and for compressed ZIP entries here. In case of a corrupted zip entry (there's a CRC for each Zip Entry and not for the whole ZIP file) a ZipException is thrown.


    You get a java.lang.NoClassDefFoundError because the JAR file cannot be loaded. There has to be an error before. I haven't checked the error handling, but I guess the ZipException is somewhere catched and logged or maybe added as cause to the NoClassDefFoundError. Since you neither share your JAR file nor any error output its hard to verify. Another possibility is that only the single corrupted ZIP Entry is skipped and others are loaded - I hadn't the time to dig more into the error handling, if you are interested have a look on it, I linked all the mentioned classes to the source code.