--- old/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java 2016-09-08 09:06:09.269992017 -0400 +++ new/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java 2016-09-08 09:06:07.374278195 -0400 @@ -153,27 +153,24 @@ boolean addAllDefaultModules = false; boolean addAllSystemModules = false; boolean addAllApplicationModules = false; - String propValue = getAndRemoveProperty("jdk.module.addmods"); - if (propValue != null) { - for (String mod: propValue.split(",")) { - switch (mod) { - case ALL_DEFAULT: - addAllDefaultModules = true; - break; - case ALL_SYSTEM: - addAllSystemModules = true; - break; - case ALL_MODULE_PATH: - addAllApplicationModules = true; - break; - default : - roots.add(mod); - } + for (String mod: getExtraAddModules()) { + switch (mod) { + case ALL_DEFAULT: + addAllDefaultModules = true; + break; + case ALL_SYSTEM: + addAllSystemModules = true; + break; + case ALL_MODULE_PATH: + addAllApplicationModules = true; + break; + default : + roots.add(mod); } } // --limit-modules - propValue = getAndRemoveProperty("jdk.module.limitmods"); + String propValue = getAndRemoveProperty("jdk.module.limitmods"); if (propValue != null) { Set mods = new HashSet<>(); for (String mod: propValue.split(",")) { @@ -392,6 +389,28 @@ } } + /** + * Returns the set of module names specified via --add-modules options + * on the command line. + */ + private static Set getExtraAddModules() { + Set modules = new HashSet<>(); + + String prefix = "jdk.module.addmods."; + int index = 0; + // the system property is removed after decoding + String value = getAndRemoveProperty(prefix + index); + while (value != null) { + for (String s : value.split(",")) { + if (s.length() > 0) modules.add(s); + } + + index++; + value = getAndRemoveProperty(prefix + index); + } + + return modules; + } /** * Process the --add-reads options to add any additional read edges that @@ -511,13 +530,8 @@ if (rhs.isEmpty()) fail("Unable to parse: " + value); - // value is (,)* - if (map.containsKey(key)) - fail(key + " specified more than once"); - - Set values = new HashSet<>(); - map.put(key, values); + Set values = map.computeIfAbsent(key, k -> new HashSet<>()); for (String s : rhs.split(",")) { if (s.length() > 0) values.add(s); } --- old/test/tools/launcher/modules/addexports/AddExportsTest.java 2016-09-08 09:06:25.982805029 -0400 +++ new/test/tools/launcher/modules/addexports/AddExportsTest.java 2016-09-08 09:06:24.186757599 -0400 @@ -202,7 +202,7 @@ /** - * --add-exports can only be specified once + * --add-exports allows duplicates */ public void testWithDuplicateOption() throws Exception { @@ -212,10 +212,9 @@ "-version") .outputTo(System.out) .errorTo(System.out) - .shouldContain("specified more than once") .getExitValue(); - assertTrue(exitValue != 0); + assertTrue(exitValue == 0); } --- old/test/tools/launcher/modules/addmods/AddModsTest.java 2016-09-08 09:06:41.525200603 -0400 +++ new/test/tools/launcher/modules/addmods/AddModsTest.java 2016-09-08 09:06:39.698670058 -0400 @@ -31,6 +31,7 @@ * @summary Basic test for java --add-modules */ +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -221,6 +222,27 @@ assertTrue(exitValue == 0); } + + + /** + * Tests {@code --add-modules} be specified more than once. + */ + public void testWithMultipleAddModules() throws Exception { + + String modulepath = MODS1_DIR.toString() + File.pathSeparator + + MODS2_DIR.toString(); + int exitValue + = executeTestJava("--module-path", modulepath, + "--add-modules", LOGGER_MODULE, + "--add-modules", TEST_MODULE, + "-m", TEST_MID, + "logger.Logger") + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); + } /** --- old/test/tools/launcher/modules/addreads/AddReadsTest.java 2016-09-08 09:06:56.849053808 -0400 +++ new/test/tools/launcher/modules/addreads/AddReadsTest.java 2016-09-08 09:06:55.128026909 -0400 @@ -182,10 +182,9 @@ "--add-reads", "m1=java.xml", "--add-reads", "m1=junit", "-m", MAIN) - .shouldContain("specified more than once") .getExitValue(); - assertTrue(exitValue != 0); + assertTrue(exitValue == 0); }