# HG changeset patch # User lancea # Date 1556831283 14400 # Node ID d890ba18f64b3492f497080611d7e9fc2623fa28 # Parent 22866513a80ede0bf4387edb04d530659314a8d5 8218875: Add new FileSystems.newFileSystem methods Reviewed-by: rriggs, alanb, clanger, dfuchs diff -r 22866513a80e -r d890ba18f64b src/java.base/share/classes/java/nio/file/FileSystems.java --- a/src/java.base/share/classes/java/nio/file/FileSystems.java Thu May 02 13:25:00 2019 -0700 +++ b/src/java.base/share/classes/java/nio/file/FileSystems.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ * systems where the contents of one or more files is treated as a file * system. * - *

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. + *

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 @@ -396,10 +395,131 @@ 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. + * + *

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. + * + *

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 env) + throws IOException + { + return newFileSystem(path, env, null); + } + + /** + * Constructs a new {@code FileSystem} to access the contents of a file as a + * file system. + * + *

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. + * + *

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. + * + *

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. + * + *

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 env, + ClassLoader loader) + throws IOException + { if (path == null) throw new NullPointerException(); - Map env = Collections.emptyMap(); - // check installed providers for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { try { diff -r 22866513a80e -r d890ba18f64b src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu May 02 13:25:00 2019 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ 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()) { diff -r 22866513a80e -r d890ba18f64b src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu May 02 13:25:00 2019 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ /* 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)); diff -r 22866513a80e -r d890ba18f64b src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java Thu May 02 13:25:00 2019 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ 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 dir = Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) { for (Path section : dir) { @@ -252,7 +252,7 @@ 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(); diff -r 22866513a80e -r d890ba18f64b test/jdk/jdk/nio/zipfs/Basic.java --- a/test/jdk/jdk/nio/zipfs/Basic.java Thu May 02 13:25:00 2019 -0700 +++ b/test/jdk/jdk/nio/zipfs/Basic.java Thu May 02 17:08:03 2019 -0400 @@ -69,7 +69,7 @@ // Test: FileSystems#newFileSystem(Path) Map 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); diff -r 22866513a80e -r d890ba18f64b test/jdk/jdk/nio/zipfs/NewFileSystemTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/nio/zipfs/NewFileSystemTests.java Thu May 02 17:08:03 2019 -0400 @@ -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 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)} + * 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, 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)} + * 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, 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)} + * will throw a {@code NullPointerException} when the specified {@code Map} + * is null + * + */ + @Test + public void testNewFileSystemPathNullMap() { + Map 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 roots = fs.getRootDirectories().iterator(); + assertTrue(roots.next().toString().equals("/")); + assertFalse(roots.hasNext()); + } +} diff -r 22866513a80e -r d890ba18f64b test/jdk/jdk/nio/zipfs/PathOps.java --- a/test/jdk/jdk/nio/zipfs/PathOps.java Thu May 02 13:25:00 2019 -0700 +++ b/test/jdk/jdk/nio/zipfs/PathOps.java Thu May 02 17:08:03 2019 -0400 @@ -604,7 +604,7 @@ // 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(); diff -r 22866513a80e -r d890ba18f64b test/jdk/jdk/nio/zipfs/ZipFSTester.java --- a/test/jdk/jdk/nio/zipfs/ZipFSTester.java Thu May 02 13:25:00 2019 -0700 +++ b/test/jdk/jdk/nio/zipfs/ZipFSTester.java Thu May 02 17:08:03 2019 -0400 @@ -81,7 +81,6 @@ */ 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 @@ // 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 @@ // 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")); diff -r 22866513a80e -r d890ba18f64b test/langtools/tools/javac/api/file/SJFM_TestBase.java --- a/test/langtools/tools/javac/api/file/SJFM_TestBase.java Thu May 02 13:25:00 2019 -0700 +++ b/test/langtools/tools/javac/api/file/SJFM_TestBase.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ List 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")) diff -r 22866513a80e -r d890ba18f64b test/langtools/tools/javac/modules/ContainsTest.java --- a/test/langtools/tools/javac/modules/ContainsTest.java Thu May 02 13:25:00 2019 -0700 +++ b/test/langtools/tools/javac/modules/ContainsTest.java Thu May 02 17:08:03 2019 -0400 @@ -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 @@ 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));