Oracle的JDK zip文件系统中存在错误,您如何编写SSCCE来重现它?

时间:2015-01-14 23:50:04

标签: java jackson java.nio.file

最新的1.7和1.8版本的JDK(7u72,8u25)中存在此错误。要求:jackson-databind 2.5.0。在Linux x86_64上测试(准确地说是Ubuntu 14.10)。

代码:

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");
    }
}

这会产生无效的zip文件:

$ 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

我最初在杰克逊的issue tracker上打开了这个错误,尽管它确实不是罪魁祸首,并且找到了一个解决方案:在JsonGenerator.Feature.AUTO_CLOSE_SOURCE中禁用ObjectMapper 。默认情况下启用的此选项告诉映射器关闭流。

虽然我想向Oracle打开这个错误,但我首先想要写一个SSCCE,但我不能。我试图关闭流两次(因为它在示例中关闭了两次),不使用try-with-resources语句等...无济于事。

你能为这个问题想出一个SSCCE吗?

1 个答案:

答案 0 :(得分:3)

我原本以为杰克逊正在做一些不愉快的事情,但事实证明,没有任何杰克逊代码就可以重现这个问题。我用两行代替了try块的主体(我很确定)做同样的事情,结果仍然是一个无效的zip文件:

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();
}