8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE
8034773: (zipfs) newOutputstream uses CREATE_NEW when no options specified
Summary: to open the new steram with appropricate open options
Reviewed-by: alanb
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed May 27 13:23:40 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed May 27 12:23:35 2015 -0700
@@ -503,6 +503,7 @@
boolean hasCreateNew = false;
boolean hasCreate = false;
boolean hasAppend = false;
+ boolean hasTruncate = false;
for (OpenOption opt: options) {
if (opt == READ)
throw new IllegalArgumentException("READ not allowed");
@@ -512,7 +513,11 @@
hasCreate = true;
if (opt == APPEND)
hasAppend = true;
+ if (opt == TRUNCATE_EXISTING)
+ hasTruncate = true;
}
+ if (hasAppend && hasTruncate)
+ throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
beginRead(); // only need a readlock, the "update()" will
try { // try to obtain a writelock when the os is
ensureOpen(); // being closed.
@@ -564,6 +569,8 @@
if (!(option instanceof StandardOpenOption))
throw new IllegalArgumentException();
}
+ if (options.contains(APPEND) && options.contains(TRUNCATE_EXISTING))
+ throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
}
// Returns a Writable/ReadByteChannel for now. Might consdier to use
@@ -711,15 +718,19 @@
if (forWrite) {
checkWritable();
if (e == null) {
- if (!options.contains(StandardOpenOption.CREATE_NEW))
- throw new NoSuchFileException(getString(path));
+ if (!options.contains(StandardOpenOption.CREATE) &&
+ !options.contains(StandardOpenOption.CREATE_NEW)) {
+ throw new NoSuchFileException(getString(path));
+ }
} else {
- if (options.contains(StandardOpenOption.CREATE_NEW))
+ if (options.contains(StandardOpenOption.CREATE_NEW)) {
throw new FileAlreadyExistsException(getString(path));
+ }
if (e.isDir())
throw new FileAlreadyExistsException("directory <"
+ getString(path) + "> exists");
}
+ options = new HashSet<>(options);
options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
} else if (e == null || e.isDir()) {
throw new NoSuchFileException(getString(path));
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Wed May 27 13:23:40 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Wed May 27 12:23:35 2015 -0700
@@ -773,7 +773,7 @@
{
if (options.length == 0)
return zfs.newOutputStream(getResolvedPath(),
- CREATE_NEW, WRITE);
+ CREATE, TRUNCATE_EXISTING, WRITE);
return zfs.newOutputStream(getResolvedPath(), options);
}
--- a/jdk/test/jdk/nio/zipfs/ZFSTests.java Wed May 27 13:23:40 2015 +0100
+++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java Wed May 27 12:23:35 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 7156873 8040059
+ * @bug 7156873 8040059 8028480 8034773
* @summary ZipFileSystem regression tests
*
* @run main ZFSTests
@@ -30,15 +30,19 @@
*/
+import java.io.OutputStream;
import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
import java.nio.file.*;
-import java.util.Map;
-import java.util.HashMap;
+import java.nio.file.spi.*;
+import java.util.*;
public class ZFSTests {
public static void main(String[] args) throws Throwable {
test7156873();
+ testOpenOptions();
}
static void test7156873() throws Throwable {
@@ -56,4 +60,44 @@
Files.deleteIfExists(dir);
}
}
+
+ static void testOpenOptions() throws Throwable {
+ Path path = Paths.get("file.zip");
+ try {
+ URI uri = URI.create("jar:" + path.toUri());
+ Map<String, Object> env = new HashMap<String, Object>();
+ env.put("create", "true");
+ try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
+ FileSystemProvider fsp = fs.provider();
+ Set<? extends OpenOption> options;
+ Path p = fs.getPath("test.txt");
+ // 8028480
+ options = EnumSet.of(StandardOpenOption.CREATE,
+ StandardOpenOption.WRITE,
+ StandardOpenOption.APPEND);
+ try (FileChannel ch = fsp.newFileChannel(p, options)) {
+ ch.write(ByteBuffer.wrap("Hello!".getBytes("ASCII")));
+ }
+ // 8034773
+ try (OutputStream os = fsp.newOutputStream(p, new OpenOption[0])) {
+ os.write("Hello2!".getBytes("ASCII"));
+ }
+ if (!"Hello2!".equals(new String(
+ Files.readAllBytes(fs.getPath("test.txt"))))) {
+ throw new RuntimeException("failed to open as truncate_existing");
+ }
+
+ options = EnumSet.of(StandardOpenOption.CREATE,
+ StandardOpenOption.APPEND,
+ StandardOpenOption.TRUNCATE_EXISTING);
+ try (FileChannel ch = fsp.newFileChannel(p, options)) {
+ throw new RuntimeException("expected IAE not thrown!");
+ } catch (IllegalArgumentException x) {
+ // expected x.printStackTrace();
+ }
+ }
+ } finally {
+ Files.deleteIfExists(path);
+ }
+ }
}