Demi
Demi

Reputation: 3611

Is it okay to catch java.util.zip.ZipError?

Why would java.util.zip.ZipError be thrown, and is it okay to catch it?

The javadoc says that it means that an unrecoverable error has occurred - but what would such an error be? I have heard that it can occur from bad zip files.

EDIT:

Looking at the java.util.zip sources shows that it is thrown when an attempt is made to access an element in the file that does not exist, but the java.util.zip.ZipFile class's internal count indicates that the element should exist. This can occur if another thread tried to close the file after the ensureOpen method checked for this, or if something went wrong in the native methods called by java.util.zip.ZipFile. This looks like it could occur if the file was changed while the Java application had it open. I don't really understand the entirity of the codebase involved though (it is big!).

Upvotes: 5

Views: 1830

Answers (2)

M. Justin
M. Justin

Reputation: 21239

It appears that JDK issue JDK-4615343 prompted the creation of ZipError in Java 6. A comment on the issue sheds some light on the existence of ZipError:

Instead of throwing an InternalError, the zip file implementation now throws java.util.zip.ZipError.

The new exception is controversial and extends InternalError. In general, this not recommended pratice but was needed for compatibility. Existing programs may have worked around this problem by catching InternalError. Such programs will continue to work but we recommend that all clients are updated to catch java.util.zip.ZipError instead.

This indicates that that ZipError is a known bad design that exists solely for backwards compatibility reasons.

Looking at the Java 8 source code likewise confirms that ZipError is only thrown by the ZipFile iteration methods: entries() and stream().

A look at the Java 9 source code reveals that Java 9 takes it a step further, and no longer throws ZipError at all.

As to why it would be thrown, the TestZipError.java source code in OpenJDK 8 shows one such scenario. A ZipError will be thrown in Microsoft Windows if a ZipFile object is created, followed by deleting the zip file in the filesystem and creating it with different entries, then iterating through the ZipFile's contents.

These details provide strong evidence that — unlike most Errors — it is in fact reasonable to catch a thrown ZipError and handle it as though it were a normal non-Error exception. Though if the code will only be running on Java 9+ one may not want to bother with the check at all, as it would be superfluous code for an impossible situation.

Upvotes: 6

Marko Topolnik
Marko Topolnik

Reputation: 200206

ZipError indicates a low-level JVM error and, although you may catch it just like any other exception, there is a chance that the whole JVM is at that moment in such a state that it shouldn't continue to run. Note that there is a separate ZipException for more regular sort of errors, like corrupt files, I/O errors etc.

Upvotes: 2

Related Questions