< prev index next >

src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java

Print this page

  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 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 package jdk.internal.jrtfs;
 26 


 27 import java.io.*;
 28 import java.net.MalformedURLException;
 29 import java.net.URL;
 30 import java.net.URLClassLoader;
 31 import java.nio.channels.*;
 32 import java.nio.file.*;
 33 import java.nio.file.DirectoryStream.Filter;
 34 import java.nio.file.attribute.*;
 35 import java.nio.file.spi.FileSystemProvider;
 36 import java.net.URI;
 37 import java.security.AccessController;
 38 import java.security.PrivilegedAction;
 39 import java.util.HashMap;
 40 import java.util.Map;
 41 import java.util.Objects;
 42 import java.util.Set;
 43 import java.util.concurrent.ExecutorService;
 44 
 45 /**
 46  * File system provider for jrt file systems. Conditionally creates jrt fs on
 47  * .jimage file or exploded modules directory of underlying JDK.
 48  *
 49  * @implNote This class needs to maintain JDK 8 source compatibility.
 50  *
 51  * It is used internally in the JDK to implement jimage/jrtfs access,
 52  * but also compiled and delivered as part of the jrtfs.jar to support access
 53  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
 54  */
 55 public final class JrtFileSystemProvider extends FileSystemProvider {
 56 
 57     private volatile FileSystem theFileSystem;
 58 
 59     public JrtFileSystemProvider() {
 60     }
 61 
 62     @Override
 63     public String getScheme() {
 64         return "jrt";
 65     }
 66 
 67     /**

 90         if (!uri.getPath().equals("/")) {
 91             throw new IllegalArgumentException("Path component should be '/'");
 92         }
 93         if (uri.getQuery() != null) {
 94             throw new IllegalArgumentException("Query component present");
 95         }
 96         if (uri.getFragment() != null) {
 97             throw new IllegalArgumentException("Fragment component present");
 98         }
 99     }
100 
101     @Override
102     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
103             throws IOException {
104         Objects.requireNonNull(env);
105         checkPermission();
106         checkUri(uri);
107         if (env.containsKey("java.home")) {
108             return newFileSystem((String)env.get("java.home"), uri, env);
109         } else {
110             return new JrtFileSystem(this, env);










111         }


112     }
113 
114     private static final String JRT_FS_JAR = "jrt-fs.jar";
115     private FileSystem newFileSystem(String targetHome, URI uri, Map<String, ?> env)
116             throws IOException {
117         Objects.requireNonNull(targetHome);
118         Path jrtfs = FileSystems.getDefault().getPath(targetHome, "lib", JRT_FS_JAR);
119         if (Files.notExists(jrtfs)) {
120             throw new IOException(jrtfs.toString() + " not exist");
121         }
122         Map<String,?> newEnv = new HashMap<>(env);
123         newEnv.remove("java.home");
124         ClassLoader cl = newJrtFsLoader(jrtfs);
125         try {
126             Class<?> c = Class.forName(JrtFileSystemProvider.class.getName(), false, cl);
127             @SuppressWarnings({ "deprecation", "suppression" })
128             Object tmp = c.newInstance();
129             return ((FileSystemProvider)tmp).newFileSystem(uri, newEnv);
130         } catch (ClassNotFoundException |
131                  IllegalAccessException |

191         }
192         if (uri.getFragment() != null) {
193             throw new IllegalArgumentException("Fragment component present");
194         }
195         String path = uri.getPath();
196         if (path == null || path.charAt(0) != '/' || path.contains("..")) {
197             throw new IllegalArgumentException("Invalid path component");
198         }
199 
200         return getTheFileSystem().getPath("/modules" + path);
201     }
202 
203     private FileSystem getTheFileSystem() {
204         checkPermission();
205         FileSystem fs = this.theFileSystem;
206         if (fs == null) {
207             synchronized (this) {
208                 fs = this.theFileSystem;
209                 if (fs == null) {
210                     try {
211                         this.theFileSystem = fs = new JrtFileSystem(this, null);

212                     } catch (IOException ioe) {
213                         throw new InternalError(ioe);
214                     }
215                 }
216             }
217         }
218         return fs;
219     }
220 
221     @Override
222     public FileSystem getFileSystem(URI uri) {
223         checkPermission();
224         checkUri(uri);
225         return getTheFileSystem();
226     }
227 
228     // Checks that the given file is a JrtPath
229     static final JrtPath toJrtPath(Path path) {
230         Objects.requireNonNull(path, "path");
231         if (!(path instanceof JrtPath)) {
232             throw new ProviderMismatchException();
233         }
234         return (JrtPath) path;
235     }
236 
237     @Override
238     public void checkAccess(Path path, AccessMode... modes) throws IOException {
239         toJrtPath(path).checkAccess(modes);
240     }
241 
242     @Override
243     public Path readSymbolicLink(Path link) throws IOException {
244         return toJrtPath(link).readSymbolicLink();
245     }
246 
247     @Override
248     public void copy(Path src, Path target, CopyOption... options)
249             throws IOException {
250         toJrtPath(src).copy(toJrtPath(target), options);
251     }
252 
253     @Override
254     public void createDirectory(Path path, FileAttribute<?>... attrs)
255             throws IOException {
256         toJrtPath(path).createDirectory(attrs);
257     }
258 
259     @Override
260     public final void delete(Path path) throws IOException {
261         toJrtPath(path).delete();
262     }
263 
264     @Override
265     public <V extends FileAttributeView> V
266             getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
267         return JrtFileAttributeView.get(toJrtPath(path), type, options);
268     }
269 
270     @Override
271     public FileStore getFileStore(Path path) throws IOException {
272         return toJrtPath(path).getFileStore();
273     }
274 
275     @Override
276     public boolean isHidden(Path path) {
277         return toJrtPath(path).isHidden();
278     }
279 
280     @Override

  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 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 package jdk.internal.jrtfs;
 26 
 27 import jdk.internal.jimage.PreviewMode;
 28 
 29 import java.io.*;
 30 import java.net.MalformedURLException;
 31 import java.net.URL;
 32 import java.net.URLClassLoader;
 33 import java.nio.channels.*;
 34 import java.nio.file.*;
 35 import java.nio.file.DirectoryStream.Filter;
 36 import java.nio.file.attribute.*;
 37 import java.nio.file.spi.FileSystemProvider;
 38 import java.net.URI;
 39 import java.security.AccessController;
 40 import java.security.PrivilegedAction;
 41 import java.util.HashMap;
 42 import java.util.Map;
 43 import java.util.Objects;
 44 import java.util.Set;
 45 import java.util.concurrent.ExecutorService;
 46 
 47 /**
 48  * File system provider for jrt file systems. Conditionally creates jrt fs on
 49  * a jimage file, or exploded modules directory of underlying JDK.
 50  *
 51  * @implNote This class needs to maintain JDK 8 source compatibility.
 52  *
 53  * It is used internally in the JDK to implement jimage/jrtfs access,
 54  * but also compiled and delivered as part of the jrtfs.jar to support access
 55  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
 56  */
 57 public final class JrtFileSystemProvider extends FileSystemProvider {
 58 
 59     private volatile FileSystem theFileSystem;
 60 
 61     public JrtFileSystemProvider() {
 62     }
 63 
 64     @Override
 65     public String getScheme() {
 66         return "jrt";
 67     }
 68 
 69     /**

 92         if (!uri.getPath().equals("/")) {
 93             throw new IllegalArgumentException("Path component should be '/'");
 94         }
 95         if (uri.getQuery() != null) {
 96             throw new IllegalArgumentException("Query component present");
 97         }
 98         if (uri.getFragment() != null) {
 99             throw new IllegalArgumentException("Fragment component present");
100         }
101     }
102 
103     @Override
104     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
105             throws IOException {
106         Objects.requireNonNull(env);
107         checkPermission();
108         checkUri(uri);
109         if (env.containsKey("java.home")) {
110             return newFileSystem((String)env.get("java.home"), uri, env);
111         } else {
112             return new JrtFileSystem(this, parsePreviewMode(env.get("previewMode")));
113         }
114     }
115 
116     // Currently this does not support specifying "for runtime", because it is
117     // expected that callers creating non-standard image readers will not be
118     // using them to read resources for the current runtime (they would just
119     // use "jrt:" URLs if they were doing that).
120     private static PreviewMode parsePreviewMode(Object envValue) {
121         if (envValue instanceof String && Boolean.parseBoolean((String) envValue)) {
122             return PreviewMode.ENABLED;
123         }
124         // Default (unspecified/null or bad parameter) is to not use preview mode.
125         return PreviewMode.DISABLED;
126     }
127 
128     private static final String JRT_FS_JAR = "jrt-fs.jar";
129     private FileSystem newFileSystem(String targetHome, URI uri, Map<String, ?> env)
130             throws IOException {
131         Objects.requireNonNull(targetHome);
132         Path jrtfs = FileSystems.getDefault().getPath(targetHome, "lib", JRT_FS_JAR);
133         if (Files.notExists(jrtfs)) {
134             throw new IOException(jrtfs.toString() + " not exist");
135         }
136         Map<String,?> newEnv = new HashMap<>(env);
137         newEnv.remove("java.home");
138         ClassLoader cl = newJrtFsLoader(jrtfs);
139         try {
140             Class<?> c = Class.forName(JrtFileSystemProvider.class.getName(), false, cl);
141             @SuppressWarnings({ "deprecation", "suppression" })
142             Object tmp = c.newInstance();
143             return ((FileSystemProvider)tmp).newFileSystem(uri, newEnv);
144         } catch (ClassNotFoundException |
145                  IllegalAccessException |

205         }
206         if (uri.getFragment() != null) {
207             throw new IllegalArgumentException("Fragment component present");
208         }
209         String path = uri.getPath();
210         if (path == null || path.charAt(0) != '/' || path.contains("..")) {
211             throw new IllegalArgumentException("Invalid path component");
212         }
213 
214         return getTheFileSystem().getPath("/modules" + path);
215     }
216 
217     private FileSystem getTheFileSystem() {
218         checkPermission();
219         FileSystem fs = this.theFileSystem;
220         if (fs == null) {
221             synchronized (this) {
222                 fs = this.theFileSystem;
223                 if (fs == null) {
224                     try {
225                         // Special constructor call for singleton instance.
226                         this.theFileSystem = fs = new JrtFileSystem(this);
227                     } catch (IOException ioe) {
228                         throw new InternalError(ioe);
229                     }
230                 }
231             }
232         }
233         return fs;
234     }
235 
236     @Override
237     public FileSystem getFileSystem(URI uri) {
238         checkPermission();
239         checkUri(uri);
240         return getTheFileSystem();
241     }
242 
243     // Checks that the given file is a JrtPath
244     static JrtPath toJrtPath(Path path) {
245         Objects.requireNonNull(path, "path");
246         if (!(path instanceof JrtPath)) {
247             throw new ProviderMismatchException();
248         }
249         return (JrtPath) path;
250     }
251 
252     @Override
253     public void checkAccess(Path path, AccessMode... modes) throws IOException {
254         toJrtPath(path).checkAccess(modes);
255     }
256 
257     @Override
258     public Path readSymbolicLink(Path link) throws IOException {
259         return toJrtPath(link).readSymbolicLink();
260     }
261 
262     @Override
263     public void copy(Path src, Path target, CopyOption... options)
264             throws IOException {
265         toJrtPath(src).copy(toJrtPath(target), options);
266     }
267 
268     @Override
269     public void createDirectory(Path path, FileAttribute<?>... attrs)
270             throws IOException {
271         toJrtPath(path).createDirectory(attrs);
272     }
273 
274     @Override
275     public void delete(Path path) throws IOException {
276         toJrtPath(path).delete();
277     }
278 
279     @Override
280     public <V extends FileAttributeView> V
281             getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
282         return JrtFileAttributeView.get(toJrtPath(path), type, options);
283     }
284 
285     @Override
286     public FileStore getFileStore(Path path) throws IOException {
287         return toJrtPath(path).getFileStore();
288     }
289 
290     @Override
291     public boolean isHidden(Path path) {
292         return toJrtPath(path).isHidden();
293     }
294 
295     @Override
< prev index next >