Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!).

like image 897
Demi Avatar asked Nov 26 '13 21:11

Demi


1 Answers

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.

like image 99
M. Justin Avatar answered Sep 24 '22 07:09

M. Justin