< prev index next >

src/java.base/share/classes/java/lang/module/ModulePath.java

Print this page




  39 import java.nio.file.Path;
  40 import java.nio.file.attribute.BasicFileAttributes;
  41 import java.util.Collections;
  42 import java.util.HashMap;
  43 import java.util.LinkedHashSet;
  44 import java.util.Map;
  45 import java.util.Objects;
  46 import java.util.Optional;
  47 import java.util.Set;
  48 import java.util.jar.Attributes;
  49 import java.util.jar.JarEntry;
  50 import java.util.jar.JarFile;
  51 import java.util.jar.Manifest;
  52 import java.util.regex.Matcher;
  53 import java.util.regex.Pattern;
  54 import java.util.stream.Collectors;
  55 import java.util.stream.Stream;
  56 import java.util.zip.ZipEntry;
  57 import java.util.zip.ZipFile;
  58 


  59 import jdk.internal.module.ConfigurableModuleFinder;
  60 import jdk.internal.perf.PerfCounter;
  61 
  62 
  63 /**
  64  * A {@code ModuleFinder} that locates modules on the file system by searching
  65  * a sequence of directories or packaged modules.
  66  *
  67  * The {@code ModuleFinder} can be configured to work in either the run-time
  68  * or link-time phases. In both cases it locates modular JAR and exploded
  69  * modules. When configured for link-time then it additionally locates
  70  * modules in JMOD files.
  71  */
  72 
  73 class ModulePath implements ConfigurableModuleFinder {
  74     private static final String MODULE_INFO = "module-info.class";
  75 
  76     // the entries on this module path
  77     private final Path[] entries;
  78     private int next;


 277                         return readJMod(entry);
 278                     throw new FindException("JMOD files not supported: " + entry);
 279                 }
 280             }
 281 
 282             // skip hidden files
 283             if (fn.startsWith(".") || Files.isHidden(entry)) {
 284                 return null;
 285             } else {
 286                 throw new FindException("Unrecognized module: " + entry);
 287             }
 288 
 289         } catch (InvalidModuleDescriptorException e) {
 290             throw new FindException("Error reading module: " + entry, e);
 291         }
 292     }
 293 
 294 
 295     // -- jmod files --
 296 
 297     private Set<String> jmodPackages(ZipFile zf) {
 298         return zf.stream()
 299             .filter(e -> e.getName().startsWith("classes/") &&
 300                     e.getName().endsWith(".class"))
 301             .map(e -> toPackageName(e.getName().substring(8)))
 302             .filter(pkg -> pkg.length() > 0) // module-info
 303             .collect(Collectors.toSet());
 304     }
 305 
 306     /**
 307      * Returns a {@code ModuleReference} to a module in jmod file on the
 308      * file system.
 309      *
 310      * @throws IOException
 311      * @throws InvalidModuleDescriptorException
 312      */
 313     private ModuleReference readJMod(Path file) throws IOException {
 314         try (ZipFile zf = new ZipFile(file.toString())) {
 315             ZipEntry ze = zf.getEntry("classes/" + MODULE_INFO);
 316             if (ze == null) {
 317                 throw new IOException(MODULE_INFO + " is missing: " + file);
 318             }
 319             ModuleDescriptor md;
 320             try (InputStream in = zf.getInputStream(ze)) {
 321                 md = ModuleDescriptor.read(in, () -> jmodPackages(zf));
 322             }
 323             return ModuleReferences.newJModModule(md, file);
 324         }
 325     }
 326 
 327 
 328     // -- JAR files --
 329 
 330     private static final String SERVICES_PREFIX = "META-INF/services/";
 331 
 332     /**
 333      * Returns a container with the service type corresponding to the name of
 334      * a services configuration file.
 335      *
 336      * For example, if called with "META-INF/services/p.S" then this method
 337      * returns a container with the value "p.S".
 338      */
 339     private Optional<String> toServiceName(String cf) {
 340         assert cf.startsWith(SERVICES_PREFIX);
 341         int index = cf.lastIndexOf("/") + 1;




  39 import java.nio.file.Path;
  40 import java.nio.file.attribute.BasicFileAttributes;
  41 import java.util.Collections;
  42 import java.util.HashMap;
  43 import java.util.LinkedHashSet;
  44 import java.util.Map;
  45 import java.util.Objects;
  46 import java.util.Optional;
  47 import java.util.Set;
  48 import java.util.jar.Attributes;
  49 import java.util.jar.JarEntry;
  50 import java.util.jar.JarFile;
  51 import java.util.jar.Manifest;
  52 import java.util.regex.Matcher;
  53 import java.util.regex.Pattern;
  54 import java.util.stream.Collectors;
  55 import java.util.stream.Stream;
  56 import java.util.zip.ZipEntry;
  57 import java.util.zip.ZipFile;
  58 
  59 import jdk.internal.jmod.JmodFile;
  60 import jdk.internal.jmod.JmodFile.Section;
  61 import jdk.internal.module.ConfigurableModuleFinder;
  62 import jdk.internal.perf.PerfCounter;
  63 
  64 
  65 /**
  66  * A {@code ModuleFinder} that locates modules on the file system by searching
  67  * a sequence of directories or packaged modules.
  68  *
  69  * The {@code ModuleFinder} can be configured to work in either the run-time
  70  * or link-time phases. In both cases it locates modular JAR and exploded
  71  * modules. When configured for link-time then it additionally locates
  72  * modules in JMOD files.
  73  */
  74 
  75 class ModulePath implements ConfigurableModuleFinder {
  76     private static final String MODULE_INFO = "module-info.class";
  77 
  78     // the entries on this module path
  79     private final Path[] entries;
  80     private int next;


 279                         return readJMod(entry);
 280                     throw new FindException("JMOD files not supported: " + entry);
 281                 }
 282             }
 283 
 284             // skip hidden files
 285             if (fn.startsWith(".") || Files.isHidden(entry)) {
 286                 return null;
 287             } else {
 288                 throw new FindException("Unrecognized module: " + entry);
 289             }
 290 
 291         } catch (InvalidModuleDescriptorException e) {
 292             throw new FindException("Error reading module: " + entry, e);
 293         }
 294     }
 295 
 296 
 297     // -- jmod files --
 298 
 299     private Set<String> jmodPackages(JmodFile jf) {
 300         return jf.stream()
 301             .filter(e -> e.section() == Section.CLASSES)
 302             .map(JmodFile.Entry::name)
 303             .map(this::toPackageName)
 304             .filter(pkg -> pkg.length() > 0) // module-info
 305             .collect(Collectors.toSet());
 306     }
 307 
 308     /**
 309      * Returns a {@code ModuleReference} to a module in jmod file on the
 310      * file system.
 311      *
 312      * @throws IOException
 313      * @throws InvalidModuleDescriptorException
 314      */
 315     private ModuleReference readJMod(Path file) throws IOException {
 316         try (JmodFile jf = new JmodFile(file)) {




 317             ModuleDescriptor md;
 318             try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
 319                 md = ModuleDescriptor.read(in, () -> jmodPackages(jf));
 320             }
 321             return ModuleReferences.newJModModule(md, file);
 322         }
 323     }
 324 
 325 
 326     // -- JAR files --
 327 
 328     private static final String SERVICES_PREFIX = "META-INF/services/";
 329 
 330     /**
 331      * Returns a container with the service type corresponding to the name of
 332      * a services configuration file.
 333      *
 334      * For example, if called with "META-INF/services/p.S" then this method
 335      * returns a container with the value "p.S".
 336      */
 337     private Optional<String> toServiceName(String cf) {
 338         assert cf.startsWith(SERVICES_PREFIX);
 339         int index = cf.lastIndexOf("/") + 1;


< prev index next >