1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ 22 package com.sun.org.apache.bcel.internal.util; 23 24 import java.io.Closeable; 25 import java.io.File; 26 import java.io.IOException; 27 import java.net.URI; 28 import java.net.URL; 29 import java.net.URLClassLoader; 30 import java.nio.file.DirectoryStream; 31 import java.nio.file.FileSystem; 32 import java.nio.file.FileSystems; 33 import java.nio.file.Files; 34 import java.nio.file.Path; 35 import java.nio.file.Paths; 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.Iterator; 39 import java.util.List; 40 import java.util.Map; 41 42 /** 43 * Wraps a Java 9 JEP 220 modular runtime image. Requires the JRT NIO file system. 44 * 45 * @since 6.3 46 */ 47 public class ModularRuntimeImage implements Closeable { 48 49 static final String MODULES_PATH = File.separator + "modules"; 50 static final String PACKAGES_PATH = File.separator + "packages"; 51 52 private final URLClassLoader classLoader; 53 private final FileSystem fileSystem; 54 55 /** 56 * Constructs a default instance. 57 * 58 * @throws IOException 59 * an I/O error occurs accessing the file system 60 */ 61 public ModularRuntimeImage() throws IOException { 62 this(null, FileSystems.getFileSystem(URI.create("jrt:/"))); 63 } 64 65 /** 66 * Constructs an instance using the JRT file system implementation from a specific Java Home. 67 * 68 * @param javaHome 69 * Path to a Java 9 or greater home. 70 * 71 * @throws IOException 72 * an I/O error occurs accessing the file system 73 */ 74 public ModularRuntimeImage(final String javaHome) throws IOException { 75 final Map<String, ?> emptyMap = Collections.emptyMap(); 76 final Path jrePath = Paths.get(javaHome); 77 final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar"); 78 this.classLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL() }); 79 this.fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, classLoader); 80 } 81 82 private ModularRuntimeImage(final URLClassLoader cl, final FileSystem fs) { 83 this.classLoader = cl; 84 this.fileSystem = fs; 85 } 86 87 @Override 88 public void close() throws IOException { 89 if (classLoader != null) { 90 if (classLoader != null) { 91 classLoader.close(); 92 } 93 if (fileSystem != null) { 94 fileSystem.close(); 95 } 96 } 97 } 98 99 /** 100 * Lists all entries in the given directory. 101 * 102 * @param dirPath 103 * directory path. 104 * @return a list of dir entries if an I/O error occurs 105 * @throws IOException 106 * an I/O error occurs accessing the file system 107 */ 108 public List<Path> list(final Path dirPath) throws IOException { 109 final List<Path> list = new ArrayList<>(); 110 try (DirectoryStream<Path> ds = Files.newDirectoryStream(dirPath)) { 111 final Iterator<Path> iterator = ds.iterator(); 112 while (iterator.hasNext()) { 113 list.add(iterator.next()); 114 } 115 } 116 return list; 117 } 118 119 /** 120 * Lists all entries in the given directory. 121 * 122 * @param dirName 123 * directory path. 124 * @return a list of dir entries if an I/O error occurs 125 * @throws IOException 126 * an I/O error occurs accessing the file system 127 */ 128 public List<Path> list(final String dirName) throws IOException { 129 return list(fileSystem.getPath(dirName)); 130 } 131 132 /** 133 * Lists all modules. 134 * 135 * @return a list of modules 136 * @throws IOException 137 * an I/O error occurs accessing the file system 138 */ 139 public List<Path> modules() throws IOException { 140 return list(MODULES_PATH); 141 } 142 143 /** 144 * Lists all packages. 145 * 146 * @return a list of modules 147 * @throws IOException 148 * an I/O error occurs accessing the file system 149 */ 150 public List<Path> packages() throws IOException { 151 return list(PACKAGES_PATH); 152 } 153 154 public FileSystem getFileSystem() { 155 return fileSystem; 156 } 157 158 }