< prev index next >

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

Print this page
8213406: (fs) More than one instance of built-in FileSystem observed in heap
Reviewed-by: alanb, cushon, weijun


  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.file;
  27 
  28 import java.nio.file.spi.FileSystemProvider;
  29 import java.net.URI;
  30 import java.io.IOException;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedAction;
  33 import java.lang.reflect.Constructor;
  34 import java.util.Collections;
  35 import java.util.Map;
  36 import java.util.ServiceConfigurationError;
  37 import java.util.ServiceLoader;
  38 
  39 import jdk.internal.misc.VM;

  40 
  41 /**
  42  * Factory methods for file systems. This class defines the {@link #getDefault
  43  * getDefault} method to get the default file system and factory methods to
  44  * construct other types of file systems.
  45  *
  46  * <p> The first invocation of any of the methods defined by this class causes
  47  * the default {@link FileSystemProvider provider} to be loaded. The default
  48  * provider, identified by the URI scheme "file", creates the {@link FileSystem}
  49  * that provides access to the file systems accessible to the Java virtual
  50  * machine. If the process of loading or initializing the default provider fails
  51  * then an unspecified error is thrown.
  52  *
  53  * <p> The first invocation of the {@link FileSystemProvider#installedProviders()
  54  * installedProviders} method, by way of invoking any of the {@code
  55  * newFileSystem} methods defined by this class, locates and loads all
  56  * installed file system providers. Installed providers are loaded using the
  57  * service-provider loading facility defined by the {@link ServiceLoader} class.
  58  * Installed providers are loaded using the system class loader. If the
  59  * system class loader cannot be found then the platform class loader is used.


  71  * may safely access files associated with the default provider but care needs
  72  * to be taken to avoid circular loading of other installed providers. If
  73  * circular loading of installed providers is detected then an unspecified error
  74  * is thrown.
  75  *
  76  * <p> This class also defines factory methods that allow a {@link ClassLoader}
  77  * to be specified when locating a provider. As with installed providers, the
  78  * provider classes are identified by placing the provider configuration file
  79  * in the resource directory {@code META-INF/services}.
  80  *
  81  * <p> If a thread initiates the loading of the installed file system providers
  82  * and another thread invokes a method that also attempts to load the providers
  83  * then the method will block until the loading completes.
  84  *
  85  * @since 1.7
  86  */
  87 
  88 public final class FileSystems {
  89     private FileSystems() { }
  90 
  91     // Built-in file system provider
  92     private static final FileSystemProvider builtinFileSystemProvider =
  93         sun.nio.fs.DefaultFileSystemProvider.create();
  94 
  95     // built-in file system
  96     private static class BuiltinFileSystemHolder {
  97         static final FileSystem builtinFileSystem =
  98             builtinFileSystemProvider.getFileSystem(URI.create("file:///"));
  99     }
 100 
 101     // lazy initialization of default file system
 102     private static class DefaultFileSystemHolder {
 103         static final FileSystem defaultFileSystem = defaultFileSystem();
 104 
 105         // returns default file system
 106         private static FileSystem defaultFileSystem() {
 107             // load default provider
 108             FileSystemProvider provider = AccessController
 109                 .doPrivileged(new PrivilegedAction<>() {
 110                     public FileSystemProvider run() {
 111                         return getDefaultProvider();
 112                     }
 113                 });
 114 
 115             // return file system
 116             return provider.getFileSystem(URI.create("file:///"));
 117         }
 118 
 119         // returns default provider
 120         private static FileSystemProvider getDefaultProvider() {
 121             FileSystemProvider provider = builtinFileSystemProvider;

 122 
 123             // if the property java.nio.file.spi.DefaultFileSystemProvider is
 124             // set then its value is the name of the default provider (or a list)
 125             String prop = "java.nio.file.spi.DefaultFileSystemProvider";
 126             String propValue = System.getProperty(prop);
 127             if (propValue != null) {
 128                 for (String cn: propValue.split(",")) {
 129                     try {
 130                         Class<?> c = Class
 131                             .forName(cn, true, ClassLoader.getSystemClassLoader());
 132                         Constructor<?> ctor = c
 133                             .getDeclaredConstructor(FileSystemProvider.class);
 134                         provider = (FileSystemProvider)ctor.newInstance(provider);
 135 
 136                         // must be "file"
 137                         if (!provider.getScheme().equals("file"))
 138                             throw new Error("Default provider must use scheme 'file'");
 139 
 140                     } catch (Exception x) {
 141                         throw new Error(x);


 172      * then an unspecified error is thrown. URI schemes are normally compared
 173      * without regard to case but for the default provider, the scheme is
 174      * required to be {@code "file"}. The first provider class is instantiated
 175      * by invoking it with a reference to the system-default provider.
 176      * The second provider class is instantiated by invoking it with a reference
 177      * to the first provider instance. The third provider class is instantiated
 178      * by invoking it with a reference to the second instance, and so on. The
 179      * last provider to be instantiated becomes the default provider; its {@code
 180      * getFileSystem} method is invoked with the URI {@code "file:///"} to
 181      * get a reference to the default file system.
 182      *
 183      * <p> Subsequent invocations of this method return the file system that was
 184      * returned by the first invocation.
 185      *
 186      * @return  the default file system
 187      */
 188     public static FileSystem getDefault() {
 189         if (VM.isModuleSystemInited()) {
 190             return DefaultFileSystemHolder.defaultFileSystem;
 191         } else {
 192             return BuiltinFileSystemHolder.builtinFileSystem;
 193         }
 194     }
 195 
 196     /**
 197      * Returns a reference to an existing {@code FileSystem}.
 198      *
 199      * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
 200      * installed} providers to locate the provider that is identified by the URI
 201      * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
 202      * without regard to case. The exact form of the URI is highly provider
 203      * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
 204      * getFileSystem} method is invoked to obtain a reference to the {@code
 205      * FileSystem}.
 206      *
 207      * <p> Once a file system created by this provider is {@link FileSystem#close
 208      * closed} it is provider-dependent if this method returns a reference to
 209      * the closed file system or throws {@link FileSystemNotFoundException}.
 210      * If the provider allows a new file system to be created with the same URI
 211      * as a file system it previously created then this method throws the
 212      * exception if invoked after the file system is closed (and before a new




  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.file;
  27 
  28 import java.nio.file.spi.FileSystemProvider;
  29 import java.net.URI;
  30 import java.io.IOException;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedAction;
  33 import java.lang.reflect.Constructor;
  34 import java.util.Collections;
  35 import java.util.Map;
  36 import java.util.ServiceConfigurationError;
  37 import java.util.ServiceLoader;
  38 
  39 import jdk.internal.misc.VM;
  40 import sun.nio.fs.DefaultFileSystemProvider;
  41 
  42 /**
  43  * Factory methods for file systems. This class defines the {@link #getDefault
  44  * getDefault} method to get the default file system and factory methods to
  45  * construct other types of file systems.
  46  *
  47  * <p> The first invocation of any of the methods defined by this class causes
  48  * the default {@link FileSystemProvider provider} to be loaded. The default
  49  * provider, identified by the URI scheme "file", creates the {@link FileSystem}
  50  * that provides access to the file systems accessible to the Java virtual
  51  * machine. If the process of loading or initializing the default provider fails
  52  * then an unspecified error is thrown.
  53  *
  54  * <p> The first invocation of the {@link FileSystemProvider#installedProviders()
  55  * installedProviders} method, by way of invoking any of the {@code
  56  * newFileSystem} methods defined by this class, locates and loads all
  57  * installed file system providers. Installed providers are loaded using the
  58  * service-provider loading facility defined by the {@link ServiceLoader} class.
  59  * Installed providers are loaded using the system class loader. If the
  60  * system class loader cannot be found then the platform class loader is used.


  72  * may safely access files associated with the default provider but care needs
  73  * to be taken to avoid circular loading of other installed providers. If
  74  * circular loading of installed providers is detected then an unspecified error
  75  * is thrown.
  76  *
  77  * <p> This class also defines factory methods that allow a {@link ClassLoader}
  78  * to be specified when locating a provider. As with installed providers, the
  79  * provider classes are identified by placing the provider configuration file
  80  * in the resource directory {@code META-INF/services}.
  81  *
  82  * <p> If a thread initiates the loading of the installed file system providers
  83  * and another thread invokes a method that also attempts to load the providers
  84  * then the method will block until the loading completes.
  85  *
  86  * @since 1.7
  87  */
  88 
  89 public final class FileSystems {
  90     private FileSystems() { }
  91 










  92     // lazy initialization of default file system
  93     private static class DefaultFileSystemHolder {
  94         static final FileSystem defaultFileSystem = defaultFileSystem();
  95 
  96         // returns default file system
  97         private static FileSystem defaultFileSystem() {
  98             // load default provider
  99             FileSystemProvider provider = AccessController
 100                 .doPrivileged(new PrivilegedAction<>() {
 101                     public FileSystemProvider run() {
 102                         return getDefaultProvider();
 103                     }
 104                 });
 105 
 106             // return file system
 107             return provider.getFileSystem(URI.create("file:///"));
 108         }
 109 
 110         // returns default provider
 111         private static FileSystemProvider getDefaultProvider() {
 112             FileSystemProvider provider =
 113                 DefaultFileSystemProvider.FILE_SYSTEM_PROVIDER;
 114 
 115             // if the property java.nio.file.spi.DefaultFileSystemProvider is
 116             // set then its value is the name of the default provider (or a list)
 117             String prop = "java.nio.file.spi.DefaultFileSystemProvider";
 118             String propValue = System.getProperty(prop);
 119             if (propValue != null) {
 120                 for (String cn: propValue.split(",")) {
 121                     try {
 122                         Class<?> c = Class
 123                             .forName(cn, true, ClassLoader.getSystemClassLoader());
 124                         Constructor<?> ctor = c
 125                             .getDeclaredConstructor(FileSystemProvider.class);
 126                         provider = (FileSystemProvider)ctor.newInstance(provider);
 127 
 128                         // must be "file"
 129                         if (!provider.getScheme().equals("file"))
 130                             throw new Error("Default provider must use scheme 'file'");
 131 
 132                     } catch (Exception x) {
 133                         throw new Error(x);


 164      * then an unspecified error is thrown. URI schemes are normally compared
 165      * without regard to case but for the default provider, the scheme is
 166      * required to be {@code "file"}. The first provider class is instantiated
 167      * by invoking it with a reference to the system-default provider.
 168      * The second provider class is instantiated by invoking it with a reference
 169      * to the first provider instance. The third provider class is instantiated
 170      * by invoking it with a reference to the second instance, and so on. The
 171      * last provider to be instantiated becomes the default provider; its {@code
 172      * getFileSystem} method is invoked with the URI {@code "file:///"} to
 173      * get a reference to the default file system.
 174      *
 175      * <p> Subsequent invocations of this method return the file system that was
 176      * returned by the first invocation.
 177      *
 178      * @return  the default file system
 179      */
 180     public static FileSystem getDefault() {
 181         if (VM.isModuleSystemInited()) {
 182             return DefaultFileSystemHolder.defaultFileSystem;
 183         } else {
 184             return DefaultFileSystemProvider.FILE_SYSTEM;
 185         }
 186     }
 187 
 188     /**
 189      * Returns a reference to an existing {@code FileSystem}.
 190      *
 191      * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
 192      * installed} providers to locate the provider that is identified by the URI
 193      * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
 194      * without regard to case. The exact form of the URI is highly provider
 195      * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
 196      * getFileSystem} method is invoked to obtain a reference to the {@code
 197      * FileSystem}.
 198      *
 199      * <p> Once a file system created by this provider is {@link FileSystem#close
 200      * closed} it is provider-dependent if this method returns a reference to
 201      * the closed file system or throws {@link FileSystemNotFoundException}.
 202      * If the provider allows a new file system to be created with the same URI
 203      * as a file system it previously created then this method throws the
 204      * exception if invoked after the file system is closed (and before a new


< prev index next >