下面列出了java.lang.module.ModuleDescriptor#packages ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns the non-exported packages of the specified module.
*/
private static Set<String> nonExportedPkgs(ModuleDescriptor md) {
// start with all packages in the module
Set<String> pkgs = new HashSet<>(md.packages());
// remove the non-qualified exported packages
md.exports().stream()
.filter(p -> !p.isQualified())
.map(Exports::source)
.forEach(pkgs::remove);
// remove the non-qualified open packages
md.opens().stream()
.filter(p -> !p.isQualified())
.map(Opens::source)
.forEach(pkgs::remove);
return pkgs;
}
/**
* Checks a configuration and the module-to-loader mapping to ensure that
* no two modules mapped to the same class loader have the same package.
* It also checks that no two automatic modules have the same package.
*
* @throws LayerInstantiationException
*/
private static void checkForDuplicatePkgs(Configuration cf,
Function<String, ClassLoader> clf)
{
// HashMap allows null keys
Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
ClassLoader loader = clf.apply(descriptor.name());
Set<String> loaderPackages
= loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
for (String pkg : descriptor.packages()) {
boolean added = loaderPackages.add(pkg);
if (!added) {
throw fail("More than one module with package %s mapped" +
" to the same class loader", pkg);
}
}
}
}
/**
* Checks for split packages between modules defined to the built-in class
* loaders.
*/
private static void checkSplitPackages(Configuration cf,
Function<String, ClassLoader> clf) {
Map<String, String> packageToModule = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
String name = descriptor.name();
ClassLoader loader = clf.apply(name);
if (loader == null || loader instanceof BuiltinClassLoader) {
for (String p : descriptor.packages()) {
String other = packageToModule.putIfAbsent(p, name);
if (other != null) {
String msg = "Package " + p + " in both module "
+ name + " and module " + other;
throw new LayerInstantiationException(msg);
}
}
}
}
}
/**
* Returns the non-exported packages of the specified module.
*/
private static Set<String> nonExportedPkgs(ModuleDescriptor md) {
// start with all packages in the module
Set<String> pkgs = new HashSet<>(md.packages());
// remove the non-qualified exported packages
md.exports().stream()
.filter(p -> !p.isQualified())
.map(Exports::source)
.forEach(pkgs::remove);
// remove the non-qualified open packages
md.opens().stream()
.filter(p -> !p.isQualified())
.map(Opens::source)
.forEach(pkgs::remove);
return pkgs;
}
/**
* Checks a configuration and the module-to-loader mapping to ensure that
* no two modules mapped to the same class loader have the same package.
* It also checks that no two automatic modules have the same package.
*
* @throws LayerInstantiationException
*/
private static void checkForDuplicatePkgs(Configuration cf,
Function<String, ClassLoader> clf)
{
// HashMap allows null keys
Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
ClassLoader loader = clf.apply(descriptor.name());
Set<String> loaderPackages
= loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
for (String pkg : descriptor.packages()) {
boolean added = loaderPackages.add(pkg);
if (!added) {
throw fail("More than one module with package %s mapped" +
" to the same class loader", pkg);
}
}
}
}
/**
* Checks for split packages between modules defined to the built-in class
* loaders.
*/
private static void checkSplitPackages(Configuration cf,
Function<String, ClassLoader> clf) {
Map<String, String> packageToModule = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
String name = descriptor.name();
ClassLoader loader = clf.apply(name);
if (loader == null || loader instanceof BuiltinClassLoader) {
for (String p : descriptor.packages()) {
String other = packageToModule.putIfAbsent(p, name);
if (other != null) {
String msg = "Package " + p + " in both module "
+ name + " and module " + other;
throw new LayerInstantiationException(msg);
}
}
}
}
}
static void checkOpenModule() {
ModuleDescriptor md = Foo.class.getModule().getDescriptor();
System.out.println(md);
if (!md.isOpen()) {
throw new RuntimeException("m4 is a open module");
}
if (md.packages().size() != 1 || !md.packages().contains("p4")) {
throw new RuntimeException("unexpected m4 packages: " + md.packages());
}
if (!md.opens().isEmpty()) {
throw new RuntimeException("unexpected m4 opens: " + md.opens());
}
}
static void checkModuleDescriptor(ModuleDescriptor md, String... packages) throws IOException {
String mainClass = md.name().replace('m', 'p') + ".Main";
if (!md.mainClass().get().equals(mainClass)) {
throw new RuntimeException(md.mainClass().toString());
}
if (expectModuleTarget) {
// ModuleTarget attribute is retained
if (! hasModuleTarget(md.name())) {
throw new RuntimeException("ModuleTarget missing for " + md.name());
}
} else {
// by default ModuleTarget attribute is dropped
if (hasModuleTarget(md.name())) {
throw new RuntimeException("ModuleTarget present for " + md.name());
}
}
Set<String> pkgs = md.packages();
if (!pkgs.equals(Set.of(packages))) {
throw new RuntimeException(pkgs + " expected: " + Set.of(packages));
}
}
/**
* Basic test of a multi-release JAR.
*/
public void testBasic() throws Exception {
String name = "m1";
ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
.requires("java.base")
.build();
Path jar = new JarBuilder(name)
.moduleInfo("module-info.class", descriptor)
.resource("p/Main.class")
.resource("p/Helper.class")
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
ModuleFinder finder = ModuleFinder.of(jar);
Optional<ModuleReference> omref = finder.find(name);
assertTrue((omref.isPresent()));
ModuleReference mref = omref.get();
// check module packages
descriptor = mref.descriptor();
Set<String> packages = descriptor.packages();
assertTrue(packages.contains("p"));
if (MULTI_RELEASE) {
assertTrue(packages.size() == 2);
assertTrue(packages.contains("p.internal"));
} else {
assertTrue(packages.size() == 1);
}
}
/**
* Test multi-release JAR as an automatic module.
*/
public void testAutomaticModule() throws Exception {
String name = "m";
Path jar = new JarBuilder(name)
.resource("p/Main.class")
.resource("p/Helper.class")
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
ModuleFinder finder = ModuleFinder.of(jar);
Optional<ModuleReference> omref = finder.find(name);
assertTrue((omref.isPresent()));
ModuleReference mref = omref.get();
// check module packages
ModuleDescriptor descriptor = mref.descriptor();
Set<String> packages = descriptor.packages();
if (MULTI_RELEASE) {
assertTrue(packages.size() == 2);
assertTrue(packages.contains("p.internal"));
} else {
assertTrue(packages.size() == 1);
}
}
private static void checkBootConflicts(FileMetadata file, Path download) throws IOException {
String filename = file.getPath().getFileName().toString();
if (!FileUtils.isZipFile(download)) {
Warning.nonZip(filename);
throw new IllegalStateException(
"File '" + filename + "' is not a valid zip file.");
}
Set<Module> modules = ModuleLayer.boot().modules();
Set<String> moduleNames = modules.stream().map(Module::getName).collect(Collectors.toSet());
Set<String> sysMods = ModuleFinder.ofSystem()
.findAll()
.stream()
.map(mr -> mr.descriptor().name())
.collect(Collectors.toSet());
ModuleDescriptor newMod = null;
try {
newMod = FileUtils.deriveModuleDescriptor(download, filename, sysMods.contains("jdk.zipfs"));
} catch (IllegalArgumentException | InvalidModuleDescriptorException | FindException e) {
Warning.illegalModule(filename);
throw e;
}
if (moduleNames.contains(newMod.name())) {
Warning.moduleConflict(newMod.name());
throw new IllegalStateException(
"Module '" + newMod.name() + "' conflicts with a module in the boot modulepath");
}
Set<String> packages = modules.stream().flatMap(m -> m.getPackages().stream()).collect(Collectors.toSet());
for (String p : newMod.packages()) {
if (packages.contains(p)) {
Warning.packageConflict(p);
throw new IllegalStateException("Package '" + p + "' in module '" + newMod.name()
+ "' conflicts with a package in the boot modulepath");
}
}
for (Requires require : newMod.requires()) {
// static requires are not mandatory
if (require.modifiers().contains(Requires.Modifier.STATIC))
continue;
String reqName = require.name();
if (StringUtils.isSystemModule(reqName)) {
if (!sysMods.contains(reqName)) {
Warning.missingSysMod(reqName);
throw new IllegalStateException("System module '" + reqName
+ "' is missing from JVM image, required by '" + newMod.name() + "'");
}
}
}
}
private void describeModule(ModuleDescriptor md,
ModuleTarget target,
ModuleHashes hashes,
String uriString)
throws IOException
{
StringBuilder sb = new StringBuilder();
sb.append(md.toNameAndVersion());
if (!uriString.equals(""))
sb.append(" ").append(uriString);
if (md.isOpen())
sb.append(" open");
if (md.isAutomatic())
sb.append(" automatic");
sb.append("\n");
// unqualified exports (sorted by package)
md.exports().stream()
.sorted(Comparator.comparing(Exports::source))
.filter(e -> !e.isQualified())
.forEach(e -> sb.append("exports ").append(e.source())
.append(toString(e.modifiers())).append("\n"));
// dependences
md.requires().stream().sorted()
.forEach(r -> sb.append("requires ").append(r.name())
.append(toString(r.modifiers())).append("\n"));
// service use and provides
md.uses().stream().sorted()
.forEach(s -> sb.append("uses ").append(s).append("\n"));
md.provides().stream()
.sorted(Comparator.comparing(Provides::service))
.forEach(p -> sb.append("provides ").append(p.service())
.append(" with")
.append(toString(p.providers()))
.append("\n"));
// qualified exports
md.exports().stream()
.sorted(Comparator.comparing(Exports::source))
.filter(Exports::isQualified)
.forEach(e -> sb.append("qualified exports ").append(e.source())
.append(" to").append(toString(e.targets()))
.append("\n"));
// open packages
md.opens().stream()
.sorted(Comparator.comparing(Opens::source))
.filter(o -> !o.isQualified())
.forEach(o -> sb.append("opens ").append(o.source())
.append(toString(o.modifiers()))
.append("\n"));
md.opens().stream()
.sorted(Comparator.comparing(Opens::source))
.filter(Opens::isQualified)
.forEach(o -> sb.append("qualified opens ").append(o.source())
.append(toString(o.modifiers()))
.append(" to").append(toString(o.targets()))
.append("\n"));
// non-exported/non-open packages
Set<String> concealed = new TreeSet<>(md.packages());
md.exports().stream().map(Exports::source).forEach(concealed::remove);
md.opens().stream().map(Opens::source).forEach(concealed::remove);
concealed.forEach(p -> sb.append("contains ").append(p).append("\n"));
md.mainClass().ifPresent(v -> sb.append("main-class ").append(v).append("\n"));
if (target != null) {
String targetPlatform = target.targetPlatform();
if (!targetPlatform.isEmpty())
sb.append("platform ").append(targetPlatform).append("\n");
}
if (hashes != null) {
hashes.names().stream().sorted().forEach(
mod -> sb.append("hashes ").append(mod).append(" ")
.append(hashes.algorithm()).append(" ")
.append(toHex(hashes.hashFor(mod)))
.append("\n"));
}
output(sb.toString());
}
private void describeModule(ModuleDescriptor md,
ModuleTarget target,
ModuleHashes hashes)
throws IOException
{
StringBuilder sb = new StringBuilder();
sb.append(md.toNameAndVersion());
if (md.isOpen())
sb.append(" open");
if (md.isAutomatic())
sb.append(" automatic");
sb.append("\n");
// unqualified exports (sorted by package)
md.exports().stream()
.sorted(Comparator.comparing(Exports::source))
.filter(e -> !e.isQualified())
.forEach(e -> sb.append("exports ").append(e.source())
.append(toString(e.modifiers())).append("\n"));
// dependences
md.requires().stream().sorted()
.forEach(r -> sb.append("requires ").append(r.name())
.append(toString(r.modifiers())).append("\n"));
// service use and provides
md.uses().stream().sorted()
.forEach(s -> sb.append("uses ").append(s).append("\n"));
md.provides().stream()
.sorted(Comparator.comparing(Provides::service))
.forEach(p -> sb.append("provides ").append(p.service())
.append(" with")
.append(toString(p.providers()))
.append("\n"));
// qualified exports
md.exports().stream()
.sorted(Comparator.comparing(Exports::source))
.filter(Exports::isQualified)
.forEach(e -> sb.append("qualified exports ").append(e.source())
.append(" to").append(toString(e.targets()))
.append("\n"));
// open packages
md.opens().stream()
.sorted(Comparator.comparing(Opens::source))
.filter(o -> !o.isQualified())
.forEach(o -> sb.append("opens ").append(o.source())
.append(toString(o.modifiers()))
.append("\n"));
md.opens().stream()
.sorted(Comparator.comparing(Opens::source))
.filter(Opens::isQualified)
.forEach(o -> sb.append("qualified opens ").append(o.source())
.append(toString(o.modifiers()))
.append(" to").append(toString(o.targets()))
.append("\n"));
// non-exported/non-open packages
Set<String> concealed = new TreeSet<>(md.packages());
md.exports().stream().map(Exports::source).forEach(concealed::remove);
md.opens().stream().map(Opens::source).forEach(concealed::remove);
concealed.forEach(p -> sb.append("contains ").append(p).append("\n"));
md.mainClass().ifPresent(v -> sb.append("main-class ").append(v).append("\n"));
if (target != null) {
String targetPlatform = target.targetPlatform();
if (!targetPlatform.isEmpty())
sb.append("platform ").append(targetPlatform).append("\n");
}
if (hashes != null) {
hashes.names().stream().sorted().forEach(
mod -> sb.append("hashes ").append(mod).append(" ")
.append(hashes.algorithm()).append(" ")
.append(toHex(hashes.hashFor(mod)))
.append("\n"));
}
out.println(sb.toString());
}