An issue is raised when an operation that closes an archive entry is called immediately after an operation that opens or begins a new entry in an archive output stream, without writing any content in between.
In Java, this specifically refers to calling closeEntry() immediately after putNextEntry() on a
ZipOutputStream or JarOutputStream.
When creating archive files (ZIP or JAR), entries are added using a three-step process:
Skipping the second step creates an empty entry in the archive. This is almost always a mistake.
Empty archive entries serve no useful purpose. In ZIP files, they waste space by storing metadata for entries with no content. In JAR files, empty entries can cause runtime errors when the application expects to load classes or resources that don’t exist.
This pattern typically occurs due to:
Since specialized archive output streams (like those for JAR files) typically extend the base archive stream class, multiple archive types are subject to this issue.
In Java, these operations correspond to putNextEntry() to start an entry, write() methods to add content, and
closeEntry() to finalize it. Both ZipOutputStream and JarOutputStream (which extends
ZipOutputStream) use this API.
Empty archive entries can cause several problems:
Write content to the archive entry between putNextEntry() and closeEntry() using the write() method. The
content can come from a byte array, file, or any other source.
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("archive.zip"));
zos.putNextEntry(new ZipEntry("empty.txt"));
zos.closeEntry(); // Noncompliant - no content written
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("archive.zip"));
zos.putNextEntry(new ZipEntry("file.txt"));
zos.write("Hello, World!".getBytes());
zos.closeEntry();