8218875: Add new FileSystems.newFileSystem methods

Reviewed-by: rriggs, alanb, clanger, dfuchs
This commit is contained in:
Lance Andersen 2019-05-02 17:08:03 -04:00
parent 2c35825433
commit 5a4cef05d6
10 changed files with 349 additions and 27 deletions
src
java.base/share/classes/java/nio/file
jdk.compiler/share/classes/com/sun/tools/javac
test

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2019, 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
@ -365,14 +365,13 @@ public final class FileSystems {
* systems where the contents of one or more files is treated as a file
* system.
*
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
* installed} providers. It invokes, in turn, each provider's {@link
* FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
* with an empty map. If a provider returns a file system then the iteration
* terminates and the file system is returned. If none of the installed
* providers return a {@code FileSystem} then an attempt is made to locate
* the provider using the given class loader. If a provider returns a file
* system then the lookup terminates and the file system is returned.
* <p> This method first attempts to locate an installed provider in exactly
* the same manner as the {@link #newFileSystem(Path, Map, ClassLoader)
* newFileSystem(Path, Map, ClassLoader)} method with an empty map. If none
* of the installed providers return a {@code FileSystem} then an attempt is
* made to locate the provider using the given class loader. If a provider
* returns a file system then the lookup terminates and the file system is
* returned.
*
* @param path
* the path to the file
@ -395,11 +394,132 @@ public final class FileSystems {
public static FileSystem newFileSystem(Path path,
ClassLoader loader)
throws IOException
{
return newFileSystem(path, Map.of(), loader);
}
/**
* Constructs a new {@code FileSystem} to access the contents of a file as a
* file system.
*
* <p> This method makes use of specialized providers that create pseudo file
* systems where the contents of one or more files is treated as a file
* system.
*
* <p> This method first attempts to locate an installed provider in exactly
* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)
* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's
* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}
* method is invoked to construct the new file system.
*
* @param path
* the path to the file
* @param env
* a map of provider specific properties to configure the file system;
* may be empty
*
* @return a new file system
*
* @throws ProviderNotFoundException
* if a provider supporting this file type cannot be located
* @throws ServiceConfigurationError
* when an error occurs while loading a service provider
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
* if a security manager is installed and it denies an unspecified
* permission
*
* @since 13
*/
public static FileSystem newFileSystem(Path path, Map<String,?> env)
throws IOException
{
return newFileSystem(path, env, null);
}
/**
* Constructs a new {@code FileSystem} to access the contents of a file as a
* file system.
*
* <p> This method makes use of specialized providers that create pseudo file
* systems where the contents of one or more files is treated as a file
* system.
*
* <p> This method first attempts to locate an installed provider in exactly
* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)
* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's
* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}
* method is invoked with an empty map to construct the new file system.
*
* @param path
* the path to the file
*
* @return a new file system
*
* @throws ProviderNotFoundException
* if a provider supporting this file type cannot be located
* @throws ServiceConfigurationError
* when an error occurs while loading a service provider
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
* if a security manager is installed and it denies an unspecified
* permission
*
* @since 13
*/
public static FileSystem newFileSystem(Path path) throws IOException {
return newFileSystem(path, Map.of(), null);
}
/**
* Constructs a new {@code FileSystem} to access the contents of a file as a
* file system.
*
* <p> This method makes use of specialized providers that create pseudo file
* systems where the contents of one or more files is treated as a file
* system.
*
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
* installed} providers. It invokes, in turn, each provider's {@link
* FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)}
* method. If a provider returns a file system then the iteration
* terminates and the file system is returned.
* If none of the installed providers return a {@code FileSystem} then
* an attempt is made to locate the provider using the given class loader.
* If a provider returns a file
* system, then the lookup terminates and the file system is returned.
*
* @param path
* the path to the file
* @param env
* a map of provider specific properties to configure the file system;
* may be empty
* @param loader
* the class loader to locate the provider or {@code null} to only
* attempt to locate an installed provider
*
* @return a new file system
*
* @throws ProviderNotFoundException
* if a provider supporting this file type cannot be located
* @throws ServiceConfigurationError
* when an error occurs while loading a service provider
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
* if a security manager is installed and it denies an unspecified
* permission
*
* @since 13
*/
public static FileSystem newFileSystem(Path path, Map<String,?> env,
ClassLoader loader)
throws IOException
{
if (path == null)
throw new NullPointerException();
Map<String,?> env = Collections.emptyMap();
// check installed providers
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
try {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2019, 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
@ -566,7 +566,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
Assert.checkNonNull(jarFSProvider, "should have been caught before!");
this.fileSystem = jarFSProvider.newFileSystem(archivePath, env);
} else {
this.fileSystem = FileSystems.newFileSystem(archivePath, null);
this.fileSystem = FileSystems.newFileSystem(archivePath, (ClassLoader)null);
}
packages = new HashMap<>();
for (Path root : fileSystem.getRootDirectories()) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2019, 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
@ -379,7 +379,7 @@ public class Locations {
/* Not a recognized extension; open it to see if
it looks like a valid zip file. */
try {
FileSystems.newFileSystem(file, null).close();
FileSystems.newFileSystem(file, (ClassLoader)null).close();
if (warn) {
log.warning(Lint.LintCategory.PATH,
Warnings.UnexpectedArchiveFile(file));

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, 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
@ -113,7 +113,7 @@ public class JDKPlatformProvider implements PlatformProvider {
SUPPORTED_JAVA_PLATFORM_VERSIONS = new TreeSet<>(NUMERICAL_COMPARATOR);
Path ctSymFile = findCtSym();
if (Files.exists(ctSymFile)) {
try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, null);
try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, (ClassLoader)null);
DirectoryStream<Path> dir =
Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) {
for (Path section : dir) {
@ -252,7 +252,7 @@ public class JDKPlatformProvider implements PlatformProvider {
try {
FileSystem fs = ctSym2FileSystem.get(file);
if (fs == null) {
ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, null));
ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, (ClassLoader)null));
}
Path root = fs.getRootDirectories().iterator().next();

@ -69,7 +69,7 @@ public class Basic {
// Test: FileSystems#newFileSystem(Path)
Map<String,?> env = Collections.emptyMap();
FileSystems.newFileSystem(jarFile, null).close();
FileSystems.newFileSystem(jarFile).close();
// Test: FileSystems#newFileSystem(URI)
URI uri = new URI("jar", jarFile.toUri().toString(), null);

@ -0,0 +1,203 @@
/*
* Copyright (c) 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Map;
import static org.testng.Assert.*;
/**
* @test
* @bug 8218875
* @summary ZIP File System tests that leverage Files.newFileSystem
* @modules jdk.zipfs
* @compile NewFileSystemTests.java
* @run testng NewFileSystemTests
* @run testng/othervm/java.security.policy=test.policy NewFileSystemTests
*/
public class NewFileSystemTests {
// The Zip file system scheme
private static final String ZIPFS_SCHEME = "jar";
// Map to used for creating a ZIP archive
private static final Map<String, String> ZIPFS_OPTIONS = Map.of("create", "true");
// Primary jar file used for testing
private static Path jarFile;
// URI for jar file used for testing
private static URI jarURI;
/**
* Create the JAR file used by the tests
*/
@BeforeClass
public void setUp() throws Exception {
jarFile = Utils.createJarFile("basic.jar",
"README");
jarURI = new URI(ZIPFS_SCHEME, jarFile.toUri().toString(), null);
}
/**
* Remove JAR file used by test as part of clean-up
*/
@AfterClass
public void tearDown() throws Exception {
Files.deleteIfExists(jarFile);
}
/**
* Validate that {@code FileSystems.newFileSystem(Path, Map<String, ?>)}
* will return a Zip file system
*
* @throws IOException
*/
@Test
public void testNewFileSystemPathMap() throws IOException {
try (FileSystem zipfs = FileSystems.newFileSystem(Path.of("basic.jar"),
ZIPFS_OPTIONS)) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(Path)}
* will return a Zip file system
*
* @throws IOException
*/
@Test
public void testNewFileSystemPath() throws IOException {
try (FileSystem zipfs = FileSystems.newFileSystem(Path.of("basic.jar"))) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(Path, ClassLoader)}
* will return a Zip file system
*
* @throws IOException
*/
@Test(dataProvider = "classLoaders")
public void testNewFileSystemPathClassLoader(ClassLoader cl) throws Exception {
try (FileSystem zipfs = FileSystems.newFileSystem(Path.of("basic.jar"),
cl)) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(Path, Map<String, ?>, ClassLoader)}
* will return a Zip file system
*
* @throws IOException
*/
@Test(dataProvider = "classLoaders")
public void testNewFileSystemPathMapClassLoader(ClassLoader cl) throws Exception {
try (FileSystem zipfs = FileSystems.newFileSystem(Path.of("basic.jar"),
ZIPFS_OPTIONS, cl)) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(URI, Map<String, ?>)}
* will return a Zip file system
*
* @throws IOException
*/
@Test
public void testNewFileSystemUriMap() throws Exception {
try (FileSystem zipfs = FileSystems.newFileSystem(jarURI, ZIPFS_OPTIONS)) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(URI, Map<String, ?>, ClassLoader)}
* will return a Zip file system
*
* @throws IOException
*/
@Test(dataProvider = "classLoaders")
public void testNewFileSystemURIMapClassLoader(ClassLoader cl) throws Exception {
try (FileSystem zipfs = FileSystems.newFileSystem(jarURI, ZIPFS_OPTIONS,
cl)) {
checkFileSystem(zipfs);
}
}
/**
* Validate that {@code FileSystems.newFileSystem(Path, Map<String, ?>)}
* will throw a {@code NullPointerException} when the specified {@code Map}
* is null
*
*/
@Test
public void testNewFileSystemPathNullMap() {
Map<String, ?> nullMap = null;
assertThrows(NullPointerException.class, () ->
FileSystems.newFileSystem(Path.of("basic.jar"), nullMap));
}
/*
* DataProvider used to verify that a Zip file system may be returned
* when specifying a class loader
*/
@DataProvider(name = "classLoaders")
private Object[][] classLoaders() {
return new Object[][]{
{null},
{ClassLoader.getSystemClassLoader()}
};
}
/**
* Validate that the given FileSystem is a Zip file system.
*
* @param fs File System to validate
*/
private void checkFileSystem(FileSystem fs) {
assertNotNull(fs, "Error: FileSystem was not returned");
assertTrue(fs.provider().getScheme().equalsIgnoreCase(ZIPFS_SCHEME));
assertTrue(fs.isOpen());
assertEquals(fs.getSeparator(), "/");
// one root
Iterator<Path> roots = fs.getRootDirectories().iterator();
assertTrue(roots.next().toString().equals("/"));
assertFalse(roots.hasNext());
}
}

@ -604,7 +604,7 @@ public class PathOps {
// create empty JAR file, test doesn't require any contents
Path emptyJar = Utils.createJarFile("empty.jar");
fs = FileSystems.newFileSystem(emptyJar, null);
fs = FileSystems.newFileSystem(emptyJar);
try {
npes();
mismatchedProviders();

@ -81,7 +81,6 @@ import static java.nio.file.StandardCopyOption.*;
*/
public class ZipFSTester {
public static void main(String[] args) throws Exception {
// create JAR file for test, actual contents don't matter
Path jarFile = Utils.createJarFile("tester.jar",
@ -146,7 +145,7 @@ public class ZipFSTester {
// copy the test jar itself in
Files.copy(Paths.get(fs0.toString()), copy.getPath("/foo.jar"));
Path zpath = copy.getPath("/foo.jar");
try (FileSystem zzfs = FileSystems.newFileSystem(zpath, null)) {
try (FileSystem zzfs = FileSystems.newFileSystem(zpath)) {
Files.copy(src, zzfs.getPath("/srcInjarjar"));
}
}
@ -254,7 +253,7 @@ public class ZipFSTester {
// test foo.jar in jar/zipfs #8034802
Path jpath = fs.getPath("/foo.jar");
System.out.println("walking: " + jpath);
try (FileSystem zzfs = FileSystems.newFileSystem(jpath, null)) {
try (FileSystem zzfs = FileSystems.newFileSystem(jpath)) {
walk(zzfs.getPath("/"));
// foojar:/srcInjarjar
checkEqual(src, zzfs.getPath("/srcInjarjar"));

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, 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
@ -160,7 +160,7 @@ class SJFM_TestBase {
List<Path> getTestZipPaths() throws IOException {
if (zipfs == null) {
Path testZip = createSourceZip();
zipfs = FileSystems.newFileSystem(testZip, null);
zipfs = FileSystems.newFileSystem(testZip);
closeables.add(zipfs);
zipPaths = Files.list(zipfs.getRootDirectories().iterator().next())
.filter(p -> p.getFileName().toString().endsWith(".java"))

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2019, 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
@ -129,7 +129,7 @@ public class ContainsTest extends ModuleTestBase {
Path c = src.resolve("p/C.java");
Path x = base.resolve("src2/p/C.java");
try (FileSystem jarFS = FileSystems.newFileSystem(jar, null);
try (FileSystem jarFS = FileSystems.newFileSystem(jar);
StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
Path jarRoot = jarFS.getRootDirectories().iterator().next();
fm.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(src, jarRoot));