49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Objects;
54 import java.util.Optional;
55 import java.util.Set;
56 import java.util.jar.Attributes;
57 import java.util.jar.JarEntry;
58 import java.util.jar.JarFile;
59 import java.util.jar.Manifest;
60 import java.util.regex.Matcher;
61 import java.util.regex.Pattern;
62 import java.util.stream.Collectors;
63 import java.util.zip.ZipException;
64 import java.util.zip.ZipFile;
65
66 import jdk.internal.jmod.JmodFile;
67 import jdk.internal.jmod.JmodFile.Section;
68 import jdk.internal.perf.PerfCounter;
69 import jdk.internal.util.jar.VersionedStream;
70
71
72 /**
73 * A {@code ModuleFinder} that locates modules on the file system by searching
74 * a sequence of directories or packaged modules. The ModuleFinder can be
75 * created to work in either the run-time or link-time phases. In both cases it
76 * locates modular JAR and exploded modules. When created for link-time then it
77 * additionally locates modules in JMOD files. The ModuleFinder can also
78 * optionally patch any modules that it locates with a ModulePatcher.
79 */
80
81 public class ModulePath implements ModuleFinder {
82 private static final String MODULE_INFO = "module-info.class";
83
84 // the version to use for multi-release modular JARs
85 private final Runtime.Version releaseVersion;
86
87 // true for the link phase (supports modules packaged in JMOD format)
88 private final boolean isLinkPhase;
89
90 // for patching modules, can be null
498 }
499
500 // Create builder, using the name derived from file name when
501 // Automatic-Module-Name not present
502 Builder builder;
503 if (moduleName != null) {
504 try {
505 builder = ModuleDescriptor.newAutomaticModule(moduleName);
506 } catch (IllegalArgumentException e) {
507 throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
508 }
509 } else {
510 builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
511 }
512
513 // module version if present
514 if (vs != null)
515 builder.version(vs);
516
517 // scan the names of the entries in the JAR file
518 Map<Boolean, Set<String>> map = VersionedStream.stream(jf)
519 .filter(e -> !e.isDirectory())
520 .map(JarEntry::getName)
521 .filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX)))
522 .collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
523 Collectors.toSet()));
524
525 Set<String> classFiles = map.get(Boolean.FALSE);
526 Set<String> configFiles = map.get(Boolean.TRUE);
527
528 // the packages containing class files
529 Set<String> packages = classFiles.stream()
530 .map(this::toPackageName)
531 .flatMap(Optional::stream)
532 .distinct()
533 .collect(Collectors.toSet());
534
535 // all packages are exported and open
536 builder.packages(packages);
537
538 // map names of service configuration files to service names
598 private static String cleanModuleName(String mn) {
599 // replace non-alphanumeric
600 mn = Patterns.NON_ALPHANUM.matcher(mn).replaceAll(".");
601
602 // collapse repeating dots
603 mn = Patterns.REPEATING_DOTS.matcher(mn).replaceAll(".");
604
605 // drop leading dots
606 if (mn.length() > 0 && mn.charAt(0) == '.')
607 mn = Patterns.LEADING_DOTS.matcher(mn).replaceAll("");
608
609 // drop trailing dots
610 int len = mn.length();
611 if (len > 0 && mn.charAt(len-1) == '.')
612 mn = Patterns.TRAILING_DOTS.matcher(mn).replaceAll("");
613
614 return mn;
615 }
616
617 private Set<String> jarPackages(JarFile jf) {
618 return VersionedStream.stream(jf)
619 .filter(e -> !e.isDirectory())
620 .map(JarEntry::getName)
621 .map(this::toPackageName)
622 .flatMap(Optional::stream)
623 .collect(Collectors.toSet());
624 }
625
626 /**
627 * Returns a {@code ModuleReference} to a module in modular JAR file on
628 * the file system.
629 *
630 * @throws IOException
631 * @throws FindException
632 * @throws InvalidModuleDescriptorException
633 */
634 private ModuleReference readJar(Path file) throws IOException {
635 try (JarFile jf = new JarFile(file.toFile(),
636 true, // verify
637 ZipFile.OPEN_READ,
638 releaseVersion))
|
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Objects;
54 import java.util.Optional;
55 import java.util.Set;
56 import java.util.jar.Attributes;
57 import java.util.jar.JarEntry;
58 import java.util.jar.JarFile;
59 import java.util.jar.Manifest;
60 import java.util.regex.Matcher;
61 import java.util.regex.Pattern;
62 import java.util.stream.Collectors;
63 import java.util.zip.ZipException;
64 import java.util.zip.ZipFile;
65
66 import jdk.internal.jmod.JmodFile;
67 import jdk.internal.jmod.JmodFile.Section;
68 import jdk.internal.perf.PerfCounter;
69
70 /**
71 * A {@code ModuleFinder} that locates modules on the file system by searching
72 * a sequence of directories or packaged modules. The ModuleFinder can be
73 * created to work in either the run-time or link-time phases. In both cases it
74 * locates modular JAR and exploded modules. When created for link-time then it
75 * additionally locates modules in JMOD files. The ModuleFinder can also
76 * optionally patch any modules that it locates with a ModulePatcher.
77 */
78
79 public class ModulePath implements ModuleFinder {
80 private static final String MODULE_INFO = "module-info.class";
81
82 // the version to use for multi-release modular JARs
83 private final Runtime.Version releaseVersion;
84
85 // true for the link phase (supports modules packaged in JMOD format)
86 private final boolean isLinkPhase;
87
88 // for patching modules, can be null
496 }
497
498 // Create builder, using the name derived from file name when
499 // Automatic-Module-Name not present
500 Builder builder;
501 if (moduleName != null) {
502 try {
503 builder = ModuleDescriptor.newAutomaticModule(moduleName);
504 } catch (IllegalArgumentException e) {
505 throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
506 }
507 } else {
508 builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
509 }
510
511 // module version if present
512 if (vs != null)
513 builder.version(vs);
514
515 // scan the names of the entries in the JAR file
516 Map<Boolean, Set<String>> map = jf.versionedStream()
517 .filter(e -> !e.isDirectory())
518 .map(JarEntry::getName)
519 .filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX)))
520 .collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
521 Collectors.toSet()));
522
523 Set<String> classFiles = map.get(Boolean.FALSE);
524 Set<String> configFiles = map.get(Boolean.TRUE);
525
526 // the packages containing class files
527 Set<String> packages = classFiles.stream()
528 .map(this::toPackageName)
529 .flatMap(Optional::stream)
530 .distinct()
531 .collect(Collectors.toSet());
532
533 // all packages are exported and open
534 builder.packages(packages);
535
536 // map names of service configuration files to service names
596 private static String cleanModuleName(String mn) {
597 // replace non-alphanumeric
598 mn = Patterns.NON_ALPHANUM.matcher(mn).replaceAll(".");
599
600 // collapse repeating dots
601 mn = Patterns.REPEATING_DOTS.matcher(mn).replaceAll(".");
602
603 // drop leading dots
604 if (mn.length() > 0 && mn.charAt(0) == '.')
605 mn = Patterns.LEADING_DOTS.matcher(mn).replaceAll("");
606
607 // drop trailing dots
608 int len = mn.length();
609 if (len > 0 && mn.charAt(len-1) == '.')
610 mn = Patterns.TRAILING_DOTS.matcher(mn).replaceAll("");
611
612 return mn;
613 }
614
615 private Set<String> jarPackages(JarFile jf) {
616 return jf.versionedStream()
617 .filter(e -> !e.isDirectory())
618 .map(JarEntry::getName)
619 .map(this::toPackageName)
620 .flatMap(Optional::stream)
621 .collect(Collectors.toSet());
622 }
623
624 /**
625 * Returns a {@code ModuleReference} to a module in modular JAR file on
626 * the file system.
627 *
628 * @throws IOException
629 * @throws FindException
630 * @throws InvalidModuleDescriptorException
631 */
632 private ModuleReference readJar(Path file) throws IOException {
633 try (JarFile jf = new JarFile(file.toFile(),
634 true, // verify
635 ZipFile.OPEN_READ,
636 releaseVersion))
|