Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug in Oracle's JDK zip filesystem, how do you write an SSCCE to reproduce it?

This bug is present in the latest 1.7 and 1.8 versions of the JDK (7u72, 8u25). Required: jackson-databind 2.5.0. Tested on Linux x86_64 (Ubuntu 14.10 to be precise).

Code:

public static void main(final String... args)
    throws IOException
{
    final Map<String, String> map
        = Collections.singletonMap("create", "true");
    final Path zipfile = Paths.get("/tmp/foo.zip");
    Files.deleteIfExists(zipfile);
    final URI uri = URI.create("jar:" + zipfile.toUri());
    final ObjectMapper mapper = new ObjectMapper();

    try (
        final FileSystem zipfs = FileSystems.newFileSystem(uri, map);
        final OutputStream out
            = Files.newOutputStream(zipfs.getPath("/t.json"));
    ) {
        mapper.writeValue(out, "hello");
    }
}

This produces an invalid zip file:

$ unzip /tmp/foo.zip 
Archive:  /tmp/foo.zip
replace t.json? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
  inflating: t.json                  
  error:  invalid compressed data to inflate

I have originally opened the bug on Jackson's issue tracker even though it really isn't the culprit here, and a solution was found to work around it: disable JsonGenerator.Feature.AUTO_CLOSE_SOURCE in the ObjectMapper. This option which is enabled by default tells the mapper to close the stream.

While I'd like to open the bug to Oracle, I'd first like to be able to write an SSCCE, but I can't. I have tried to close the stream twice (since it is closed twice in the example), not to use a try-with-resources statement etc... To no avail.

Can you come up with an SSCCE for this problem?

like image 413
fge Avatar asked Jan 14 '15 23:01

fge


People also ask

How can I read the content of a Zip file without unzipping it in Java?

Methods. getComment(): String – returns the zip file comment, or null if none. getEntry(String name): ZipEntry – returns the zip file entry for the specified name, or null if not found. getInputStream(ZipEntry entry) : InputStream – Returns an input stream for reading the contents of the specified zip file entry.

What is zip file system?

The zip file system provider treats a zip or JAR file as a file system and provides the ability to manipulate the contents of the file. The zip file system provider creates multiple file systems — one file system for each zip or JAR file.

What is a file system in Java?

A file system is the factory for several types of objects: The getPath method converts a system dependent path string, returning a Path object that may be used to locate and access a file. The getPathMatcher method is used to create a PathMatcher that performs match operations on paths.


1 Answers

I had thought Jackson was doing something untoward, but it turns out one can reproduce the problem without any Jackson code. I replaced the body of the try block with two lines that (I'm pretty sure) do the same thing, and the result is still an invalid zip file:

try (
    final FileSystem zipfs = FileSystems.newFileSystem(uri, map);
    final OutputStream out
        = Files.newOutputStream(zipfs.getPath("/t.json"));
) {
    out.write("\"hello\"".getBytes(StandardCharsets.US_ASCII));
    out.close();
}
like image 196
VGR Avatar answered Oct 02 '22 19:10

VGR