diff --git a/src/java.base/share/classes/java/lang/module/ResolvedModule.java b/src/java.base/share/classes/java/lang/module/ResolvedModule.java index 7309e291b4b..0237dbe2959 100644 --- a/src/java.base/share/classes/java/lang/module/ResolvedModule.java +++ b/src/java.base/share/classes/java/lang/module/ResolvedModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,6 +97,8 @@ public final class ResolvedModule { /** * Returns the set of resolved modules that this resolved module reads. + * The readability relation is reflexive (every module reads itself). The + * set of resolved modules returned by this method does not include itself. * * @return A possibly-empty unmodifiable set of resolved modules that * this resolved module reads diff --git a/src/java.base/share/classes/java/lang/module/Resolver.java b/src/java.base/share/classes/java/lang/module/Resolver.java index 3cd0254ba4e..bff087fb674 100644 --- a/src/java.base/share/classes/java/lang/module/Resolver.java +++ b/src/java.base/share/classes/java/lang/module/Resolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -497,7 +497,6 @@ final class Resolver { * and m2 reads m3. */ private Map> makeGraph(Configuration cf) { - int moduleCount = nameToReference.size(); // the "reads" graph starts as a module dependence graph and @@ -537,9 +536,7 @@ final class Resolver { } // populate g1 and g2 with the dependences from the selected modules - Map nameToResolved = HashMap.newHashMap(moduleCount); - for (ModuleReference mref : nameToReference.values()) { ModuleDescriptor descriptor = mref.descriptor(); String name = descriptor.name(); @@ -595,8 +592,7 @@ final class Resolver { String name2 = descriptor2.name(); if (!name.equals(name2)) { - ResolvedModule m2 - = computeIfAbsent(nameToResolved, name2, cf, mref2); + ResolvedModule m2 = computeIfAbsent(nameToResolved, name2, cf, mref2); reads.add(m2); if (descriptor2.isAutomatic()) requiresTransitive.add(m2); @@ -622,29 +618,33 @@ final class Resolver { g2.put(m1, requiresTransitive); } - // Iteratively update g1 until there are no more requires transitive - // to propagate + // Iteratively update g1 until there are no more requires transitive to propagate boolean changed; List toAdd = new ArrayList<>(); do { changed = false; - for (Set m1Reads : g1.values()) { - for (ResolvedModule m2 : m1Reads) { - Set m2RequiresTransitive = g2.get(m2); - if (m2RequiresTransitive != null) { - for (ResolvedModule m3 : m2RequiresTransitive) { - if (!m1Reads.contains(m3)) { - // m1 reads m2, m2 requires transitive m3 - // => need to add m1 reads m3 - toAdd.add(m3); + for (Map.Entry> e : g1.entrySet()) { + ResolvedModule m1 = e.getKey(); + // automatic module already reads all selected modules so nothing to propagate + if (!m1.descriptor().isAutomatic()) { + Set m1Reads = e.getValue(); + for (ResolvedModule m2 : m1Reads) { + Set m2RequiresTransitive = g2.get(m2); + if (m2RequiresTransitive != null) { + for (ResolvedModule m3 : m2RequiresTransitive) { + if (!m1Reads.contains(m3)) { + // m1 reads m2, m2 requires transitive m3 + // => need to add m1 reads m3 + toAdd.add(m3); + } } } } - } - if (!toAdd.isEmpty()) { - m1Reads.addAll(toAdd); - toAdd.clear(); - changed = true; + if (!toAdd.isEmpty()) { + m1Reads.addAll(toAdd); + toAdd.clear(); + changed = true; + } } } } while (changed); diff --git a/test/jdk/java/lang/module/AutomaticModulesTest.java b/test/jdk/java/lang/module/AutomaticModulesTest.java index a1977ae8774..84240be22fe 100644 --- a/test/jdk/java/lang/module/AutomaticModulesTest.java +++ b/test/jdk/java/lang/module/AutomaticModulesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,12 @@ /** * @test - * @bug 8142968 8253751 8262944 + * @bug 8142968 8253751 8262944 8314986 * @library /test/lib * @build AutomaticModulesTest * jdk.test.lib.util.JarUtils * jdk.test.lib.util.ModuleUtils - * @run testng AutomaticModulesTest + * @run junit AutomaticModulesTest * @summary Basic tests for automatic modules */ @@ -54,75 +54,69 @@ import java.util.stream.Stream; import jdk.test.lib.util.JarUtils; import jdk.test.lib.util.ModuleUtils; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.params.provider.Arguments.arguments; -@Test public class AutomaticModulesTest { - private static final Path USER_DIR = Path.of(System.getProperty("user.dir")); - @DataProvider(name = "jarnames") - public Object[][] createJarNames() { - return new Object[][] { + // JAR file name to expected module name / version + static Stream jarNames() { + return Stream.of( + arguments( "foo.jar", "foo" ), + arguments( "foo4j.jar", "foo4j" ), - // JAR file name module-name[/version] + arguments( "foo1.jar", "foo1" ), + arguments( "foo10.jar", "foo10" ), - { "foo.jar", "foo" }, - { "foo4j.jar", "foo4j", }, + arguments( "foo-1.jar", "foo/1" ), + arguments( "foo-1.2.jar", "foo/1.2" ), + arguments( "foo-1.2.3.jar", "foo/1.2.3" ), + arguments( "foo-1.2.3.4.jar", "foo/1.2.3.4" ), - { "foo1.jar", "foo1" }, - { "foo10.jar", "foo10" }, + arguments( "foo-10.jar", "foo/10" ), + arguments( "foo-10.20.jar", "foo/10.20" ), + arguments( "foo-10.20.30.jar", "foo/10.20.30" ), + arguments( "foo-10.20.30.40.jar", "foo/10.20.30.40" ), - { "foo-1.jar", "foo/1" }, - { "foo-1.2.jar", "foo/1.2" }, - { "foo-1.2.3.jar", "foo/1.2.3" }, - { "foo-1.2.3.4.jar", "foo/1.2.3.4" }, + arguments( "foo-bar.jar", "foo.bar" ), + arguments( "foo-bar-1.jar", "foo.bar/1" ), + arguments( "foo-bar-1.2.jar", "foo.bar/1.2" ), + arguments( "foo-bar-10.jar", "foo.bar/10" ), + arguments( "foo-bar-10.20.jar", "foo.bar/10.20" ), - { "foo-10.jar", "foo/10" }, - { "foo-10.20.jar", "foo/10.20" }, - { "foo-10.20.30.jar", "foo/10.20.30" }, - { "foo-10.20.30.40.jar", "foo/10.20.30.40" }, + arguments("foo.bar1.jar", "foo.bar1" ), + arguments( "foo.bar10.jar", "foo.bar10" ), - { "foo-bar.jar", "foo.bar" }, - { "foo-bar-1.jar", "foo.bar/1" }, - { "foo-bar-1.2.jar", "foo.bar/1.2"}, - { "foo-bar-10.jar", "foo.bar/10" }, - { "foo-bar-10.20.jar", "foo.bar/10.20" }, + arguments( "foo-1.2-SNAPSHOT.jar", "foo/1.2-SNAPSHOT" ), + arguments( "foo-bar-1.2-SNAPSHOT.jar", "foo.bar/1.2-SNAPSHOT" ), - { "foo.bar1.jar", "foo.bar1" }, - { "foo.bar10.jar", "foo.bar10" }, - - { "foo-1.2-SNAPSHOT.jar", "foo/1.2-SNAPSHOT" }, - { "foo-bar-1.2-SNAPSHOT.jar", "foo.bar/1.2-SNAPSHOT" }, - - { "foo--bar-1.0.jar", "foo.bar/1.0" }, - { "-foo-bar-1.0.jar", "foo.bar/1.0" }, - { "foo-bar--1.0.jar", "foo.bar/1.0" }, - - }; + arguments( "foo--bar-1.0.jar", "foo.bar/1.0" ), + arguments( "-foo-bar-1.0.jar", "foo.bar/1.0" ), + arguments( "foo-bar--1.0.jar", "foo.bar/1.0" ) + ); } // JAR file names that do not map to a legal module name - @DataProvider(name = "badjarnames") - public Object[][] createBadNames() { - return new Object[][]{ - - { ".jar", null }, - { "_.jar", null }, - - { "foo.1.jar", null }, - { "1foo.jar", null }, - { "foo.1bar.jar", null }, - - }; + static Stream barJarNames() { + return Stream.of( + ".jar", + "_.jar", + "foo.1.jar", + "1foo.jar", + "foo.1bar.jar" + ); } /** * Test mapping of JAR file names to module names */ - @Test(dataProvider = "jarnames") + @ParameterizedTest + @MethodSource("jarNames") public void testNames(String fn, String mid) throws IOException { String[] s = mid.split("/"); String mn = s[0]; @@ -143,19 +137,20 @@ public class AutomaticModulesTest { ModuleDescriptor descriptor = mref.get().descriptor(); assertTrue(descriptor.isAutomatic()); - assertEquals(descriptor.name(), mn); + assertEquals(mn, descriptor.name()); if (vs == null) { assertFalse(descriptor.version().isPresent()); } else { - assertEquals(descriptor.version().get().toString(), vs); + assertEquals(vs, descriptor.version().get().toString()); } } /** * Test impossible mapping of JAR files to modules names */ - @Test(dataProvider = "badjarnames", expectedExceptions = FindException.class) - public void testBadNames(String fn, String ignore) throws IOException { + @ParameterizedTest + @MethodSource("barJarNames") + public void testBadNames(String fn) throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); Path jf = dir.resolve(fn); @@ -163,37 +158,36 @@ public class AutomaticModulesTest { createDummyJarFile(jf); // should throw FindException - ModuleFinder.of(dir).findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } - @DataProvider(name = "modulenames") - public Object[][] createModuleNames() { - return new Object[][] { - { "foo", null }, - { "foo", "1.0" }, - { "foo.bar", null }, - { "foo.bar", "1.0" }, - { "class_", null }, - { "class_", "1.0" }, - }; + // Automatic-Module-Name attribute values and version in JAR file name + static Stream automaticModuleNames() { + return Stream.of( + arguments( "foo", null ), + arguments( "foo", "1.0" ), + arguments( "foo.bar", null ), + arguments( "foo.bar", "1.0" ), + arguments( "class_", null ), + arguments( "class_", "1.0" ) + ); } - @DataProvider(name = "badmodulenames") - public Object[][] createBadModuleNames() { - return new Object[][] { - { "", null }, - { "", "1.0" }, - { "666", null }, - { "666", "1.0" }, - { "foo.class", null }, - { "foo.class", "1.0" }, - }; + // Bad Automatic-Module-Name attribute values + static Stream badAutomaticModuleNames() { + return Stream.of( + "", + "666", + "foo.class" + ); } /** * Test JAR files with the Automatic-Module-Name attribute */ - @Test(dataProvider = "modulenames") + @ParameterizedTest + @MethodSource("automaticModuleNames") public void testAutomaticModuleNameAttribute(String name, String vs) throws IOException { @@ -218,27 +212,26 @@ public class AutomaticModulesTest { ModuleReference mref = finder.find(name).get(); ModuleDescriptor descriptor = mref.descriptor(); - assertEquals(descriptor.name(), name); - assertEquals(descriptor.version() + assertEquals(name, descriptor.name()); + assertEquals(vs, descriptor.version() .map(ModuleDescriptor.Version::toString) - .orElse(null), vs); + .orElse(null)); } /** * Test JAR files with the Automatic-Module-Name attribute with a value * that is not a legal module name. */ - @Test(dataProvider = "badmodulenames", expectedExceptions = FindException.class) - public void testBadAutomaticModuleNameAttribute(String name, String ignore) - throws IOException - { - // should throw FindException - testAutomaticModuleNameAttribute(name, null); + @ParameterizedTest + @MethodSource("badAutomaticModuleNames") + public void testBadAutomaticModuleNameAttribute(String name) throws IOException { + assertThrows(FindException.class, () -> testAutomaticModuleNameAttribute(name, null)); } /** * Test all packages are exported */ + @Test public void testPackages() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), @@ -263,6 +256,7 @@ public class AutomaticModulesTest { * Test class files in JAR file where the entry does not correspond to a * legal package name. */ + @Test public void testBadPackage() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), "p/C1.class", "p-/C2.class"); @@ -284,6 +278,7 @@ public class AutomaticModulesTest { /** * Test non-class resources in a JAR file. */ + @Test public void testNonClassResources() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), @@ -307,17 +302,18 @@ public class AutomaticModulesTest { /** * Test .class file in unnamed package (top-level directory) */ - @Test(expectedExceptions = FindException.class) + @Test public void testClassInUnnamedPackage() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), "Mojo.class"); - ModuleFinder finder = ModuleFinder.of(dir); - finder.findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } /** * Test JAR file with META-INF/services configuration file */ + @Test public void testServicesConfiguration() throws IOException { String service = "p.S"; String provider = "p.S1"; @@ -345,27 +341,25 @@ public class AutomaticModulesTest { ModuleDescriptor descriptor = mref.get().descriptor(); assertTrue(descriptor.provides().size() == 1); ModuleDescriptor.Provides provides = descriptor.provides().iterator().next(); - assertEquals(provides.service(), service); + assertEquals(service, provides.service()); assertTrue(provides.providers().size() == 1); assertTrue(provides.providers().contains((provider))); } // META-INF/services files that don't map to legal service names - @DataProvider(name = "badservices") - public Object[][] createBadServices() { - return new Object[][] { - - // service type provider type - { "-", "p.S1" }, - { ".S", "p.S1" }, - }; + static Stream badServices() { + return Stream.of( + arguments( "-", "p.S1" ), + arguments( ".S", "p.S1" ) + ); } /** * Test JAR file with META-INF/services configuration file with bad * values or names. */ - @Test(dataProvider = "badservices") + @ParameterizedTest + @MethodSource("badServices") public void testBadServicesNames(String service, String provider) throws IOException { @@ -383,22 +377,20 @@ public class AutomaticModulesTest { } // META-INF/services configuration file entries that are not legal - @DataProvider(name = "badproviders") - public Object[][] createBadProviders() { - return new Object[][] { - - // service type provider type - { "p.S", "-" }, - { "p.S", "p..S1" }, - { "p.S", "S1." }, - }; + static Stream badProviders() { + return Stream.of( + arguments("p.S", "-"), + arguments("p.S", "p..S1"), + arguments("p.S", "S1.") + ); } /** * Test JAR file with META-INF/services configuration file with bad * values or names. */ - @Test(dataProvider = "badproviders", expectedExceptions = FindException.class) + @ParameterizedTest + @MethodSource("badProviders") public void testBadProviderNames(String service, String provider) throws IOException { @@ -418,14 +410,15 @@ public class AutomaticModulesTest { JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir); // should throw FindException - ModuleFinder.of(dir).findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } /** * Test JAR file with META-INF/services configuration file listing a * provider that is not in the module. */ - @Test(expectedExceptions = FindException.class) + @Test public void testMissingProviderPackage() throws IOException { Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp"); @@ -438,31 +431,20 @@ public class AutomaticModulesTest { Path jarfile = dir.resolve("m.jar"); JarUtils.createJarFile(jarfile, tmpdir); - // catch FindException, inspect its cause's type and details, and rethrow - var expectedMessage = "Provider class q.P not in JAR file " + jarfile.getFileName(); - try { - ModuleFinder.of(dir).findAll(); - } catch (FindException exception) { - if (exception.getCause() instanceof InvalidModuleDescriptorException imde) { - var actualMessage = imde.getMessage(); - if (actualMessage.equals(expectedMessage)) { - throw exception; // rethrow as expected - } - throw new AssertionError( - """ - Unexpected detail message in InvalidModuleDescriptorException: - Expected message -> '%s' - Actual message -> '%s' - """.formatted(expectedMessage, actualMessage)); - } - throw new AssertionError("Unexpected exception cause: " + exception.getCause()); - } + // FindException should be thrown with InvalidModuleDescriptorException as cause + var finder = ModuleFinder.of(dir); + FindException ex = assertThrows(FindException.class, () -> finder.findAll()); + Throwable cause = ex.getCause(); + assertTrue(cause instanceof InvalidModuleDescriptorException); + var imde = (InvalidModuleDescriptorException) cause; + assertEquals("Provider class q.P not in JAR file " + jarfile.getFileName(), imde.getMessage()); } /** * Test that a JAR file with a Main-Class attribute results * in a module with a main class. */ + @Test public void testMainClass() throws IOException { String mainClass = "p.Main"; @@ -481,27 +463,24 @@ public class AutomaticModulesTest { Configuration cf = resolve(parent, finder, "m"); ModuleDescriptor descriptor = findDescriptor(cf, "m"); - - assertTrue(descriptor.mainClass().isPresent()); - assertEquals(descriptor.mainClass().get(), mainClass); + assertEquals(mainClass, descriptor.mainClass().get()); } - // Main-Class files that do not map to a legal qualified type name - @DataProvider(name = "badmainclass") - public Object[][] createBadMainClass() { - return new Object[][] { - { "p..Main", null }, - { "p-.Main", null }, - - }; + // Main-Class attribute values that do not map to a legal qualified type name + static Stream badMainClasses() { + return Stream.of( + "p..Main", + "p-.Main" + ); } /** * Test that a JAR file with a Main-Class attribute that is not a qualified * type name. */ - @Test(dataProvider = "badmainclass") - public void testBadMainClass(String mainClass, String ignore) throws IOException { + @ParameterizedTest + @MethodSource("badMainClasses") + public void testBadMainClass(String mainClass) throws IOException { Manifest man = new Manifest(); Attributes attrs = man.getMainAttributes(); attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); @@ -521,6 +500,7 @@ public class AutomaticModulesTest { /** * Test that a JAR file with a Main-Class attribute that is not in the module */ + @Test public void testMissingMainClassPackage() throws IOException { Manifest man = new Manifest(); Attributes attrs = man.getMainAttributes(); @@ -544,6 +524,7 @@ public class AutomaticModulesTest { * b* * c* */ + @Test public void testConfiguration1() throws Exception { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -588,13 +569,14 @@ public class AutomaticModulesTest { assertTrue(a.reads().contains(c)); assertTrue(b.reads().contains(a)); + assertFalse(b.reads().contains(b)); assertTrue(b.reads().contains(c)); testReadAllBootModules(cf, "b"); // b reads all modules in boot layer assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer - } /** @@ -604,6 +586,7 @@ public class AutomaticModulesTest { * c* * d* */ + @Test public void testInConfiguration2() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -660,12 +643,14 @@ public class AutomaticModulesTest { assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); assertTrue(c.reads().contains(d)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer assertTrue(d.reads().contains(a)); assertTrue(d.reads().contains(b)); assertTrue(d.reads().contains(c)); + assertFalse(d.reads().contains(d)); testReadAllBootModules(cf, "d"); // d reads all modules in boot layer } @@ -676,6 +661,7 @@ public class AutomaticModulesTest { * c* * d* */ + @Test public void testInConfiguration3() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -732,18 +718,16 @@ public class AutomaticModulesTest { assertTrue(b.reads().contains(d)); assertTrue(b.reads().contains(base)); - assertTrue(reads(cf, "b", "c")); - assertTrue(reads(cf, "b", "d")); - assertTrue(reads(cf, "b", "java.base")); - assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); assertTrue(c.reads().contains(d)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer assertTrue(d.reads().contains(a)); assertTrue(d.reads().contains(b)); assertTrue(d.reads().contains(c)); + assertFalse(d.reads().contains(d)); testReadAllBootModules(cf, "d"); // d reads all modules in boot layer } @@ -751,6 +735,7 @@ public class AutomaticModulesTest { * Basic test to ensure that no automatic modules are resolved when * an automatic module is not a root or required by other modules. */ + @Test public void testInConfiguration4() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") @@ -780,6 +765,7 @@ public class AutomaticModulesTest { * Basic test to ensure that if an automatic module is resolved then * all observable automatic modules are resolved. */ + @Test public void testInConfiguration5() throws IOException { // m1 requires m2 ModuleDescriptor descriptor1 @@ -836,6 +822,7 @@ public class AutomaticModulesTest { assertTrue(auto1.reads().contains(m1)); assertTrue(auto1.reads().contains(m2)); + assertFalse(auto1.reads().contains(auto1)); assertTrue(auto1.reads().contains(auto2)); assertTrue(auto1.reads().contains(auto3)); assertTrue(auto1.reads().contains(base)); @@ -843,6 +830,7 @@ public class AutomaticModulesTest { assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(m2)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); assertTrue(auto2.reads().contains(auto3)); assertTrue(auto2.reads().contains(base)); @@ -850,6 +838,7 @@ public class AutomaticModulesTest { assertTrue(auto3.reads().contains(m2)); assertTrue(auto3.reads().contains(auto1)); assertTrue(auto3.reads().contains(auto2)); + assertFalse(auto3.reads().contains(auto3)); assertTrue(auto3.reads().contains(base)); } @@ -859,6 +848,7 @@ public class AutomaticModulesTest { * automatic modules that are found by the after finder and not shadowed * by the before finder, or parent configurations, should also be resolved. */ + @Test public void testInConfiguration6() throws IOException { // m1 requires auto1 ModuleDescriptor descriptor1 @@ -918,12 +908,14 @@ public class AutomaticModulesTest { assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); assertTrue(auto2.reads().contains(auto3)); assertTrue(auto2.reads().contains(base)); assertTrue(auto3.reads().contains(m1)); assertTrue(auto3.reads().contains(auto1)); assertTrue(auto3.reads().contains(auto2)); + assertFalse(auto3.reads().contains(auto3)); assertTrue(auto3.reads().contains(base)); } @@ -933,6 +925,7 @@ public class AutomaticModulesTest { * automatic module in a parent configuration then it should read all * automatic modules in the parent configuration. */ + @Test public void testInConfiguration7() throws Exception { // m1 requires auto1 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") @@ -964,11 +957,13 @@ public class AutomaticModulesTest { assertTrue(auto1.reads().contains(base)); assertTrue(auto1.reads().contains(m1)); + assertFalse(auto1.reads().contains(auto1)); assertTrue(auto1.reads().contains(auto2)); assertTrue(auto2.reads().contains(base)); assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); // m2 requires auto1 ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2") @@ -999,7 +994,7 @@ public class AutomaticModulesTest { * b* contains p * c* contains p */ - @Test(expectedExceptions = { ResolutionException.class }) + @Test public void testDuplicateSuppliers1() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1018,7 +1013,7 @@ public class AutomaticModulesTest { ModuleFinder.of(dir)); Configuration parent = ModuleLayer.boot().configuration(); - resolve(parent, finder, "a"); + assertThrows(ResolutionException.class, () -> resolve(parent, finder, "a")); } /** @@ -1026,7 +1021,7 @@ public class AutomaticModulesTest { * a contains p, requires b* * b* contains p */ - @Test(expectedExceptions = { ResolutionException.class }) + @Test public void testDuplicateSuppliers2() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1044,12 +1039,13 @@ public class AutomaticModulesTest { ModuleFinder.of(dir)); Configuration parent = ModuleLayer.boot().configuration(); - resolve(parent, finder, "a"); + assertThrows(ResolutionException.class, () -> resolve(parent, finder, "a")); } /** * Basic test of layer containing automatic modules */ + @Test public void testInLayer() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1091,6 +1087,7 @@ public class AutomaticModulesTest { /** * Test miscellaneous methods. */ + @Test public void testMisc() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); Path m_jar = createDummyJarFile(dir.resolve("m.jar"), "p/T.class"); @@ -1132,13 +1129,10 @@ public class AutomaticModulesTest { * configuration. */ static void testReadAllBootModules(Configuration cf, String mn) { - Set bootModules = ModuleLayer.boot().modules().stream() .map(Module::getName) .collect(Collectors.toSet()); - bootModules.forEach(other -> assertTrue(reads(cf, mn, other))); - } /** @@ -1202,5 +1196,4 @@ public class AutomaticModulesTest { { return createDummyJarFile(jarfile, null, entries); } - }