1 /* 2 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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 26 package org.openjdk.jigsaw; 27 28 import java.lang.module.*; 29 import java.io.*; 30 import java.net.URI; 31 import java.security.CodeSigner; 32 import java.security.SignatureException; 33 import java.util.*; 34 35 import static org.openjdk.jigsaw.Trace.*; 36 37 38 /** 39 * The abstract base class for module libraries 40 * 41 * @see SimpleLibrary 42 */ 43 44 public abstract class Library 45 extends LocatableCatalog 46 { 47 48 private static File systemLibraryPath = null; 49 50 /** 51 * <p> The system module library's path </p> 52 */ 53 public static synchronized File systemLibraryPath() { 54 if (systemLibraryPath == null) { 55 systemLibraryPath 56 = new File(new File(System.getProperty("java.home"), 57 "lib"), 58 "modules"); 59 } 60 return systemLibraryPath; 61 } 62 63 /** 64 * <p> Open the system module library </p> 65 */ 66 public static Library openSystemLibrary() 67 throws IOException 68 { 69 return SimpleLibrary.open(systemLibraryPath()); 70 } 71 72 private static final JigsawModuleSystem jms 73 = JigsawModuleSystem.instance(); 74 75 protected Library() { } 76 77 public abstract int majorVersion(); 78 public abstract int minorVersion(); 79 80 public abstract Library parent(); 81 82 /** 83 * <p> Read the module-info class bytes for the module with the given 84 * identifier, from this library only. </p> 85 * 86 * @param mid 87 * The identifier of the module being sought 88 * 89 * @return A byte array containing the content of the named module's 90 * <tt>module-info.class</tt> file, or {@code null} if no such 91 * module is present in this library 92 * 93 * @throws IllegalArgumentException 94 * If the given module identifier is not a Jigsaw module 95 * identifier 96 */ 97 protected abstract byte[] readLocalModuleInfoBytes(ModuleId mid) 98 throws IOException; 99 100 public byte[] readModuleInfoBytes(ModuleId mid) 101 throws IOException 102 { 103 Library lib = this; 104 while (lib != null) { 105 byte[] bs = lib.readLocalModuleInfoBytes(mid); 106 if (bs != null) 107 return bs; 108 lib = lib.parent(); 109 } 110 return null; 111 } 112 113 public ModuleInfo readLocalModuleInfo(ModuleId mid) 114 throws IOException 115 { 116 byte[] bs = readLocalModuleInfoBytes(mid); 117 if (bs != null) 118 return jms.parseModuleInfo(bs); 119 return null; 120 } 121 122 /** 123 * Read the class bytes of the given class within the given module in this 124 * library. 125 * 126 * @param mid 127 * The module's identifier 128 * 129 * @param className 130 * The binary name of the requested class 131 * 132 * @return The requested bytes, or {@code null} if the named module does 133 * not define such a class 134 * 135 * @throws IllegalArgumentException 136 * If the given module identifier is not a Jigsaw module 137 * identifier 138 */ 139 public abstract byte[] readLocalClass(ModuleId mid, String className) 140 throws IOException; 141 142 /** 143 * Read the class bytes of the given class within the given module, in this 144 * library or in a parent library. 145 * 146 * @param mid 147 * The module's identifier 148 * 149 * @param className 150 * The binary name of the requested class 151 * 152 * @return The requested bytes, or {@code null} if the named module does 153 * not define such a class 154 * 155 * @throws IllegalArgumentException 156 * If the given module identifier is not a Jigsaw module 157 * identifier 158 */ 159 public byte[] readClass(ModuleId mid, String className) 160 throws IOException 161 { 162 for (Library l = this; l != null; l = l.parent()) { 163 byte[] bs = l.readLocalClass(mid, className); 164 if (bs != null) 165 return bs; 166 } 167 return null; 168 } 169 170 /** 171 * Return a list of the public and, optionally, all other classes defined 172 * by the named module in this library. 173 * 174 * @param mid 175 * The module's identifier 176 * 177 * @param all 178 * Whether non-public classes should be included 179 * 180 * @return The requested class names, or null if the named module does not 181 * exist in this library 182 * 183 * @throws IllegalArgumentException 184 * If the given module identifier is not a Jigsaw module 185 * identifier 186 */ 187 public abstract List<String> listLocalClasses(ModuleId mid, boolean all) 188 throws IOException; 189 190 /** 191 * Read the stored {@link Configuration} of the named module. 192 * 193 * @param mid 194 * The module's identifier 195 * 196 * @return The named module's {@link Configuration}, or null if the named 197 * module does not exist in this library 198 * 199 * @throws IllegalArgumentException 200 * If the given module identifier is not a Jigsaw module 201 * identifier 202 */ 203 public abstract Configuration<Context> readConfiguration(ModuleId mid) 204 throws IOException; 205 206 /** 207 * <p> Install one or more modules into this library. </p> 208 * 209 * <p> The modules are first copied from the locations specified in the 210 * given manifests, and then the configurations of any affected root 211 * modules in the library are recomputed. </p> 212 * 213 * @param mfs 214 * The manifests describing the contents of the modules to be 215 * installed 216 */ 217 public abstract void installFromManifests(Collection<Manifest> mfs) 218 throws ConfigurationException, IOException; 219 220 /** 221 * <p> Install one or more module files into this library. </p> 222 * 223 * @param mfs 224 * The module files to be installed 225 * 226 * @param verifySignature 227 * Perform signature verification of signed module files, if true. 228 * Otherwise treat the module files as unsigned. 229 * 230 * @throws ConfigurationException 231 * If a valid configuration cannot be computed 232 * 233 * @throws IOException 234 * If an I/O error occurs while accessing the module library 235 * 236 * @throws SignatureException 237 * If an error occurs while validating the signature 238 * 239 * @throws ModuleFileParserException 240 * If there is an error processing one the underlying module files 241 */ 242 public abstract void install(Collection<File> mfs, boolean verifySignature) 243 throws ConfigurationException, IOException, SignatureException; 244 245 /** 246 * <p> Resolve the given collection of {@linkplain 247 * java.lang.module.ModuleIdQuery module-id queries} against this 248 * library. </p> 249 * 250 * @param midqs 251 * A non-empty collection of {@link java.lang.module.ModuleIdQuery 252 * ModuleIdQuery objects} 253 * 254 * @throws ConfigurationException 255 * If a valid {@link Resolution} cannot be computed 256 * 257 * @throws IOException 258 * If an I/O error occurs while accessing the module library 259 */ 260 public abstract Resolution resolve(Collection<ModuleIdQuery> midqs) 261 throws ConfigurationException, IOException; 262 263 /** 264 * <p> Install any modules required by the given {@linkplain Resolution 265 * resolution}, and configure all of its root modules. </p> 266 * 267 * @param res 268 * A {@link Resolution} previously computed by the 269 * {@link Library#resolve resolve} method 270 * 271 * @param verifySignature 272 * Perform signature verification, if true 273 * 274 * @throws ConfigurationException 275 * If a valid configuration cannot be computed 276 * 277 * @throws IOException 278 * If an I/O error occurs while accessing the module library 279 * 280 * @throws SignatureException 281 * If an error occurs while validating the signature 282 * 283 * @throws ModuleFileParserException 284 * If there is an error processing the underlying module file 285 * required by the given resolution 286 */ 287 public abstract void install(Resolution res, boolean verifySignature) 288 throws ConfigurationException, IOException, SignatureException; 289 290 /** 291 * Remove one or more modules from this library. 292 * 293 * @param mids 294 * The module identifiers 295 * 296 * @param dry 297 * Perform a dry run (no changes to the module library), if true. 298 * Otherwise the modules may be removed. 299 * 300 * @throws ConfigurationException 301 * If the configuration of any root modules in the library 302 * require any of the given modules 303 * 304 * @throws IOException 305 * If an I/O error occurs while accessing the module library, or 306 * removing any of the module's files. Any such exceptions are 307 * caught internally. If only one is caught, then it is re-thrown. 308 * If more than one exception is caught, then the second and 309 * following exceptions are added as suppressed exceptions of the 310 * first one caught, which is then re-thrown. 311 */ 312 public abstract void remove(List<ModuleId> mids, boolean dry) 313 throws ConfigurationException, IOException; 314 315 /** 316 * Forcibly remove one or more modules from this library. 317 * 318 * <p> No regard is given to configuration of any root modules in the 319 * library that may require any of the given modules. </p> 320 * 321 * @param mids 322 * The module identifiers 323 * 324 * @throws IOException 325 * If an I/O error occurs while accessing the module library, or 326 * removing any of the module's files. Any such exceptions are 327 * caught internally. If only one is caught, then it is re-thrown. 328 * If more than one exception is caught, then the second and 329 * following exceptions are added as suppressed exceptions of the 330 * first one caught, which is then re-thrown. 331 */ 332 public abstract void removeForcibly(List<ModuleId> mids) 333 throws IOException; 334 335 /** 336 * Find a resource within the given module in this library. 337 * 338 * @param mid 339 * The module's identifier 340 * 341 * @param rn 342 * The name of the requested resource, in the usual 343 * slash-separated form 344 * 345 * @return A {@code File} object naming the location of the resource, 346 * or {@code null} if the named module does not define that 347 * resource 348 */ 349 // ## Returning file or jar URIs here is EVIL! 350 // ## Define a jmod: hierarchical URI scheme? 351 public abstract URI findLocalResource(ModuleId mid, String rn) 352 throws IOException; 353 354 /** 355 * Find a native library within the given module in this library. 356 * 357 * @param mid 358 * The module's identifier 359 * 360 * @param name 361 * The name of the requested library, in platform-specific 362 * form, <i>i.e.</i>, that returned by the {@link 363 * java.lang.System#mapLibraryName System.mapLibraryName} method 364 * 365 * @return A {@code File} object naming the location of the native library, 366 * or {@code null} if the named module does not contain such a 367 * library 368 */ 369 public abstract File findLocalNativeLibrary(ModuleId mid, String name) 370 throws IOException; 371 372 /** 373 * <p> Return a file path to the given module's classes. </p> 374 * 375 * @param mid 376 * The module's identifier 377 * 378 * @return A {@code File} object naming the location of the module's 379 * classes, or {@code null} if the named module does not exist 380 */ 381 public abstract File classPath(ModuleId mid) 382 throws IOException; 383 384 385 public abstract RemoteRepositoryList repositoryList() throws IOException; 386 387 /** 388 * <p> Read the CodeSigners for the module with the given identifier, from 389 * this library only. </p> 390 * 391 * @param mid 392 * The identifier of the module being sought 393 * 394 * @return An array of CodeSigners, or {@code null} if the module is not 395 * signed 396 * 397 * @throws IllegalArgumentException 398 * If the given module identifier is not a Jigsaw module 399 * identifier 400 * 401 * @throws IOException 402 * If an I/O error occurs while accessing the module library 403 */ 404 public abstract CodeSigner[] readLocalCodeSigners(ModuleId mid) 405 throws IOException; 406 407 }