--- old/src/java.base/share/classes/java/lang/module/Resolver.java 2017-03-21 13:43:57.520043810 +0000 +++ new/src/java.base/share/classes/java/lang/module/Resolver.java 2017-03-21 13:43:57.323030292 +0000 @@ -47,6 +47,7 @@ import jdk.internal.module.ModuleHashes; import jdk.internal.module.ModuleReferenceImpl; +import jdk.internal.module.ModuleTarget; /** * The resolver used by {@link Configuration#resolve} and {@link @@ -69,11 +70,9 @@ // module constraints on target platform private String osName; private String osArch; - private String osVersion; String osName() { return osName; } String osArch() { return osArch; } - String osVersion() { return osVersion; } /** * @throws IllegalArgumentException if there are more than one parent and @@ -110,16 +109,6 @@ } } } - value = parent.osVersion(); - if (value != null) { - if (osVersion == null) { - osVersion = value; - } else { - if (!value.equals(osVersion)) { - failParentConflict("OS version", osVersion, value); - } - } - } } } @@ -318,13 +307,15 @@ * the target platform with the constraints of other modules. */ private void addFoundModule(ModuleReference mref) { - ModuleDescriptor descriptor = mref.descriptor(); - nameToReference.put(descriptor.name(), mref); + String mn = mref.descriptor().name(); + + if (mref instanceof ModuleReferenceImpl) { + ModuleTarget target = ((ModuleReferenceImpl)mref).moduleTarget(); + if (target != null) + checkTargetConstraints(mn, target); + } - if (descriptor.osName().isPresent() - || descriptor.osArch().isPresent() - || descriptor.osVersion().isPresent()) - checkTargetConstraints(descriptor); + nameToReference.put(mn, mref); } /** @@ -332,58 +323,44 @@ * conflict with the constraints of other modules resolved so far or * modules in parent configurations. */ - private void checkTargetConstraints(ModuleDescriptor descriptor) { - String value = descriptor.osName().orElse(null); + private void checkTargetConstraints(String mn, ModuleTarget target) { + String value = target.osName(); if (value != null) { if (osName == null) { osName = value; } else { if (!value.equals(osName)) { - failTargetConstraint(descriptor); + failTargetConstraint(mn, target); } } } - value = descriptor.osArch().orElse(null); + value = target.osArch(); if (value != null) { if (osArch == null) { osArch = value; } else { if (!value.equals(osArch)) { - failTargetConstraint(descriptor); - } - } - } - value = descriptor.osVersion().orElse(null); - if (value != null) { - if (osVersion == null) { - osVersion = value; - } else { - if (!value.equals(osVersion)) { - failTargetConstraint(descriptor); + failTargetConstraint(mn, target); } } } } - private void failTargetConstraint(ModuleDescriptor md) { - String s1 = targetAsString(osName, osArch, osVersion); - String s2 = targetAsString(md); - findFail("Module %s has constraints on target platform that conflict" + - " with other modules: %s, %s", md.name(), s1, s2); + private void failTargetConstraint(String mn, ModuleTarget target) { + String s1 = targetAsString(osName, osArch); + String s2 = targetAsString(target.osName(), target.osArch()); + findFail("Module %s has constraints on target platform (%s) that" + + " conflict with other modules: %s", mn, s1, s2); } - private String targetAsString(ModuleDescriptor descriptor) { - String osName = descriptor.osName().orElse(null); - String osArch = descriptor.osArch().orElse(null); - String osVersion = descriptor.osVersion().orElse(null); - return targetAsString(osName, osArch, osVersion); + private String targetAsString(ModuleTarget target) { + return targetAsString(target.osName(), target.osArch()); } - private String targetAsString(String osName, String osArch, String osVersion) { + private String targetAsString(String osName, String osArch) { return new StringJoiner("-") .add(Objects.toString(osName, "*")) .add(Objects.toString(osArch, "*")) - .add(Objects.toString(osVersion, "*")) .toString(); } @@ -712,16 +689,30 @@ /** - * Checks the readability graph to ensure that no two modules export the - * same package to a module. This includes the case where module M has - * a local package P and M reads another module that exports P to M. - * Also checks the uses/provides of module M to ensure that it reads a - * module that exports the package of the service type to M. + * Checks the readability graph to ensure that + *
    + *
  1. A module does not read two or more modules with the same name. + * This includes the case where a module reads another another with the + * same name as itself.

  2. + *
  3. Two or more modules in the configuration don't export the same + * package to a module that reads both. This includes the case where a + * module {@code M} containing package {@code p} reads another module + * that exports {@code p} to {@code M}.

  4. + *
  5. A module {@code M} doesn't declare that it "{@code uses p.S}" + * or "{@code provides p.S with ...}" but package {@code p} is neither + * in module {@code M} nor exported to {@code M} by any module that + * {@code M} reads.

  6. + *
*/ private void checkExportSuppliers(Map> graph) { for (Map.Entry> e : graph.entrySet()) { ModuleDescriptor descriptor1 = e.getKey().descriptor(); + String name1 = descriptor1.name(); + + // the names of the modules that are read (including self) + Set names = new HashSet<>(); + names.add(name1); // the map of packages that are local or exported to descriptor1 Map packageToExporter = new HashMap<>(); @@ -737,9 +728,20 @@ for (ResolvedModule endpoint : reads) { ModuleDescriptor descriptor2 = endpoint.descriptor(); + String name2 = descriptor2.name(); + if (descriptor2 != descriptor1 && !names.add(name2)) { + if (name2.equals(name1)) { + resolveFail("Module %s reads another module named %s", + name1, name1); + } else{ + resolveFail("Module %s reads more than one module named %s", + name1, name2); + } + } + if (descriptor2.isAutomatic()) { // automatic modules read self and export all packages - if (descriptor2 != descriptor1){ + if (descriptor2 != descriptor1) { for (String source : descriptor2.packages()) { ModuleDescriptor supplier = packageToExporter.putIfAbsent(source, descriptor2);