< prev index next >
src/java.base/share/classes/java/lang/module/Resolver.java
Print this page
@@ -45,10 +45,11 @@
import java.util.StringJoiner;
import java.util.stream.Collectors;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleReferenceImpl;
+import jdk.internal.module.ModuleTarget;
/**
* The resolver used by {@link Configuration#resolve} and {@link
* Configuration#resolveAndBind}.
*
@@ -67,15 +68,13 @@
private final Map<String, ModuleReference> nameToReference = new HashMap<>();
// 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
* the constraints on the target platform conflict
*/
@@ -108,20 +107,10 @@
if (!value.equals(osArch)) {
failParentConflict("OS architecture", osArch, value);
}
}
}
- value = parent.osVersion();
- if (value != null) {
- if (osVersion == null) {
- osVersion = value;
- } else {
- if (!value.equals(osVersion)) {
- failParentConflict("OS version", osVersion, value);
- }
- }
- }
}
}
private void failParentConflict(String constraint, String s1, String s2) {
String msg = "Parents have conflicting constraints on target "
@@ -316,76 +305,64 @@
/**
* Add the module to the nameToReference map. Also check any constraints on
* 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);
}
/**
* Check that the module's constraints on the target platform do not
* 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();
}
/**
@@ -710,20 +687,34 @@
return m;
}
/**
- * 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
+ * <ol>
+ * <li><p> 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. </p></li>
+ * <li><p> 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}. </p></li>
+ * <li><p> 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. </p></li>
+ * </ol>
*/
private void checkExportSuppliers(Map<ResolvedModule, Set<ResolvedModule>> graph) {
for (Map.Entry<ResolvedModule, Set<ResolvedModule>> e : graph.entrySet()) {
ModuleDescriptor descriptor1 = e.getKey().descriptor();
+ String name1 = descriptor1.name();
+
+ // the names of the modules that are read (including self)
+ Set<String> names = new HashSet<>();
+ names.add(name1);
// the map of packages that are local or exported to descriptor1
Map<String, ModuleDescriptor> packageToExporter = new HashMap<>();
// local packages
@@ -735,13 +726,24 @@
// descriptor1 reads descriptor2
Set<ResolvedModule> reads = e.getValue();
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);
// descriptor2 and 'supplier' export source to descriptor1
< prev index next >