Skip to content

Commit e336d04

Browse files
committed
8294193: Files.createDirectories throws FileAlreadyExistsException for a symbolic link whose target is an existing directory
Backport-of: 169a5d48afbc6627f36a768c17c2a5e56219d9c7
1 parent 35c1ebc commit e336d04

File tree

3 files changed

+127
-37
lines changed

3 files changed

+127
-37
lines changed

src/java.base/share/classes/java/nio/file/Files.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ private static void createAndCheckIsDirectory(Path dir,
806806
try {
807807
createDirectory(dir, attrs);
808808
} catch (FileAlreadyExistsException x) {
809-
if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
809+
if (!isDirectory(dir))
810810
throw x;
811811
}
812812
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.io.IOException;
25+
import java.nio.file.FileAlreadyExistsException;
26+
import java.nio.file.Files;
27+
import java.nio.file.Path;
28+
29+
import static org.testng.Assert.*;
30+
import org.testng.SkipException;
31+
import org.testng.annotations.Test;
32+
33+
/*
34+
* @test
35+
* @bug 8032220 8293792
36+
* @summary Test java.nio.file.Files.createDirectories method
37+
* @library ..
38+
* @run testng CreateDirectories
39+
*/
40+
public class CreateDirectories {
41+
42+
/**
43+
* Test Files.createDirectories symbolic file with an existing directory.
44+
*/
45+
@Test
46+
public void testSymlinkDir() throws Exception {
47+
// create a temp dir as the "root" in which we will run our tests.
48+
final Path top = TestUtil.createTemporaryDirectory();
49+
if (!TestUtil.supportsLinks(top)) {
50+
System.out.println("Skipping tests since symbolic links isn't " +
51+
"supported under directory "+ top);
52+
throw new SkipException("Symbolic links not supported");
53+
}
54+
System.out.println("Running tests under directory " + top.toAbsolutePath());
55+
final Path fooDir = Files.createDirectory(top.resolve("foo"));
56+
assertTrue(Files.isDirectory(fooDir),
57+
fooDir + " was expected to be a directory but wasn't");
58+
59+
// now create a symlink to the "foo" dir
60+
final Path symlink = Files.createSymbolicLink(top.resolve("symlinkToFoo"),
61+
fooDir.toAbsolutePath());
62+
assertTrue(Files.isSymbolicLink(symlink),
63+
symlink + " was expected to be a symlink but wasn't");
64+
assertTrue(Files.isDirectory(symlink),
65+
symlink + " was expected to be a directory but wasn't");
66+
67+
// now create a directory under the symlink (which effectively creates a directory under
68+
// "foo")
69+
final Path barDir = Files.createDirectory(symlink.resolve("bar"));
70+
assertTrue(Files.isDirectory(barDir),
71+
barDir + " was expected to be a directory but wasn't");
72+
// ultimately, we now have this directory structure:
73+
// <root-dir>
74+
// |--- foo
75+
// | |--- bar
76+
// |
77+
// |--- symlinkToFoo -> (links to) <absolute-path-to-root-dir>/foo
78+
79+
80+
// now call Files.createDirectories on each of these existing directory/symlink paths
81+
// and expect each one to succeed
82+
Files.createDirectories(fooDir); // ./<root-dir>/foo
83+
Files.createDirectories(symlink); // ./<root-dir>/symlinkToFoo
84+
Files.createDirectories(barDir); // ./<root-dir>/symlinkToFoo/bar
85+
}
86+
87+
/**
88+
* Tests Files.createDirectories
89+
*/
90+
@Test
91+
public void testCreateDirectories() throws IOException {
92+
final Path tmpdir = TestUtil.createTemporaryDirectory();
93+
// a no-op
94+
Files.createDirectories(tmpdir);
95+
96+
// create one directory
97+
Path subdir = tmpdir.resolve("a");
98+
Files.createDirectories(subdir);
99+
assertTrue(Files.isDirectory(subdir), subdir + " was expected to be a directory," +
100+
" but wasn't");
101+
102+
// create parents
103+
subdir = subdir.resolve("b/c/d");
104+
Files.createDirectories(subdir);
105+
assertTrue(Files.isDirectory(subdir), subdir + " was expected to be a directory," +
106+
" but wasn't");
107+
108+
// existing file is not a directory
109+
Path file = Files.createFile(tmpdir.resolve("x"));
110+
try {
111+
Files.createDirectories(file);
112+
throw new RuntimeException("failure expected");
113+
} catch (FileAlreadyExistsException x) { }
114+
try {
115+
Files.createDirectories(file.resolve("y"));
116+
throw new RuntimeException("failure expected");
117+
} catch (IOException x) { }
118+
119+
// the root directory always exists
120+
Path root = Path.of("/");
121+
Files.createDirectories(root);
122+
Files.createDirectories(root.toAbsolutePath());
123+
}
124+
}

test/jdk/java/nio/file/Files/Misc.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
*/
2323

2424
/* @test
25-
* @bug 4313887 6838333 8005566 8032220 8215467 8255576 8286160
26-
* @summary Unit test for miscellenous methods in java.nio.file.Files
25+
* @bug 4313887 6838333 8005566 8215467 8255576 8286160
26+
* @summary Unit test for miscellaneous methods in java.nio.file.Files
2727
* @library .. /test/lib
2828
* @build jdk.test.lib.Platform
2929
* @run main Misc
@@ -51,7 +51,6 @@ public class Misc {
5151
public static void main(String[] args) throws IOException {
5252
Path dir = TestUtil.createTemporaryDirectory();
5353
try {
54-
testCreateDirectories(dir);
5554
testIsHidden(dir);
5655
testIsSameFile(dir);
5756
testFileTypeMethods(dir);
@@ -61,39 +60,6 @@ public static void main(String[] args) throws IOException {
6160
}
6261
}
6362

64-
/**
65-
* Tests createDirectories
66-
*/
67-
static void testCreateDirectories(Path tmpdir) throws IOException {
68-
// a no-op
69-
createDirectories(tmpdir);
70-
71-
// create one directory
72-
Path subdir = tmpdir.resolve("a");
73-
createDirectories(subdir);
74-
assertTrue(exists(subdir));
75-
76-
// create parents
77-
subdir = subdir.resolve("b/c/d");
78-
createDirectories(subdir);
79-
assertTrue(exists(subdir));
80-
81-
// existing file is not a directory
82-
Path file = createFile(tmpdir.resolve("x"));
83-
try {
84-
createDirectories(file);
85-
throw new RuntimeException("failure expected");
86-
} catch (FileAlreadyExistsException x) { }
87-
try {
88-
createDirectories(file.resolve("y"));
89-
throw new RuntimeException("failure expected");
90-
} catch (IOException x) { }
91-
92-
// the root directory always exists
93-
Path root = Path.of("/");
94-
Files.createDirectories(root);
95-
Files.createDirectories(root.toAbsolutePath());
96-
}
9763

9864
/**
9965
* Tests isHidden

0 commit comments

Comments
 (0)