diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPaths.java b/java.api.common/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPaths.java index 10c6606c50c5..65a27972891a 100644 --- a/java.api.common/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPaths.java +++ b/java.api.common/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPaths.java @@ -676,7 +676,7 @@ public List getResources() { bestSoFar[1] = Boolean.TRUE; return (List) bestSoFar[0]; } - final Collection newModuleInfos = new ArrayDeque<>(); + final Collection newModuleInfos = new LinkedHashSet<>(); final List newActiveProjectSourceRoots = new ArrayList<>(); collectProjectSourceRoots(systemModules, newActiveProjectSourceRoots); collectProjectSourceRoots(userModules, newActiveProjectSourceRoots); @@ -922,9 +922,9 @@ public List getResources() { newModuleInfos }); setCache(res); - final Collection added = new ArrayList<>(newModuleInfos); + final Collection added = new LinkedHashSet<>(newModuleInfos); added.removeAll(moduleInfos); - final Collection removed = new ArrayList<>(moduleInfos); + final Collection removed = new LinkedHashSet<>(moduleInfos); removed.removeAll(newModuleInfos); removed.stream().forEach((f) -> FileUtil.removeFileChangeListener(this, f)); added.stream().forEach((f) -> FileUtil.addFileChangeListener(this, f)); diff --git a/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPathsTest.java b/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPathsTest.java index 7414cd8b4bd0..b30f8246bdb7 100644 --- a/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPathsTest.java +++ b/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/classpath/ModuleClassPathsTest.java @@ -64,6 +64,7 @@ import org.netbeans.modules.java.api.common.TestProject; import org.netbeans.modules.java.api.common.project.ProjectProperties; import org.netbeans.modules.java.j2seplatform.platformdefinition.Util; +import org.netbeans.modules.java.source.BootClassPathUtil; import org.netbeans.modules.parsing.api.indexing.IndexingManager; import org.netbeans.spi.java.classpath.ClassPathFactory; import org.netbeans.spi.java.classpath.ClassPathProvider; @@ -583,6 +584,25 @@ public void testPatchModuleWithSourcePatch_UnscannedBaseModule() throws Exceptio collectEntries(cp)); } + public void testDuplicateSourceDirsNETBEANS_817() throws Exception { + if (systemModules == null) { + System.out.println("No jdk 9 home configured."); //NOI18N + return; + } + assertNotNull(src); + final FileObject moduleInfo = createModuleInfo(src, "Modle", "java.logging"); //NOI18N + final ClassPath cp = ClassPathFactory.createClassPath(ModuleClassPaths.createModuleInfoBasedPath( + systemModules, + org.netbeans.spi.java.classpath.support.ClassPathSupport.createProxyClassPath(src, src), + systemModules, + ClassPath.EMPTY, + null, + null)); + final Collection resURLs = collectEntries(cp); + final Collection expectedURLs = reads(systemModules, NamePredicate.create("java.logging")); //NOI18N + assertEquals(expectedURLs, resURLs); + } + private static void setSourceLevel( @NonNull final Project prj, @NonNull final String sourceLevel) throws IOException { diff --git a/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java b/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java index 68e4a4bd26a4..425b5208942c 100644 --- a/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java +++ b/java.source.base/src/org/netbeans/modules/java/source/indexing/APTUtils.java @@ -447,7 +447,7 @@ boolean verifyAttributes(FileObject fo, boolean checkOnly) { return vote; } } - final String cmpOptsStr = JavacParser.validateCompilerOptions(compilerOptions.getArguments()) + final String cmpOptsStr = JavacParser.validateCompilerOptions(compilerOptions.getArguments(), null) .stream() .collect(Collectors.joining(" ")); //NOI18N if (JavaIndex.ensureAttributeValue(url, COMPILER_OPTIONS, cmpOptsStr, checkOnly)) { diff --git a/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java b/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java index 3aa15da75282..c237d5735b2a 100644 --- a/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java +++ b/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java @@ -871,7 +871,7 @@ private static JavacTaskImpl createJavacTask( options.add("-proc:none"); // NOI18N, Disable annotation processors } if (compilerOptions != null) { - for (String compilerOption : validateCompilerOptions(compilerOptions.getArguments())) { + for (String compilerOption : validateCompilerOptions(compilerOptions.getArguments(), validatedSourceLevel)) { options.add(compilerOption); } } @@ -1029,8 +1029,9 @@ public static com.sun.tools.javac.code.Source validateSourceLevel( } @NonNull - public static List validateCompilerOptions(@NonNull final List options) { + public static List validateCompilerOptions(@NonNull final List options, @NullAllowed com.sun.tools.javac.code.Source sourceLevel) { final List res = new ArrayList<>(); + boolean allowModularOptions = sourceLevel == null || com.sun.tools.javac.code.Source.lookup("9").compareTo(sourceLevel) <= 0; boolean xmoduleSeen = false; for (int i = 0; i < options.size(); i++) { String option = options.get(i); @@ -1047,12 +1048,13 @@ public static List validateCompilerOptions(@NonNull final List xmoduleSeen = true; } else if (option.equals("-parameters") || option.startsWith("-Xlint")) { //NOI18N res.add(option); - } else if ( + } else if (( option.startsWith("--add-modules") || //NOI18N option.startsWith("--limit-modules") || //NOI18N option.startsWith("--add-exports") || //NOI18N option.startsWith("--add-reads") || - option.startsWith(OPTION_PATCH_MODULE)) { + option.startsWith(OPTION_PATCH_MODULE)) && + allowModularOptions) { int idx = option.indexOf('='); if (idx > 0) { res.add(option); diff --git a/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java b/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java index 2f9b75bf7eb0..b1591661a4c8 100644 --- a/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java +++ b/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java @@ -30,7 +30,9 @@ import java.io.InputStream; import java.net.URL; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -393,7 +395,18 @@ private Source guessSourceLevel(boolean objectOnBCP, boolean sbOnCP, boolean acO return JavacParser.validateSourceLevel("1.7", info, false); } - + + public void testValidateCompilerOptions() { + List input = Arrays.asList("--add-exports", "foo/bar=foobar", + "--add-exports=foo2/bar=foobar", + "--limit-modules", "foo", + "--add-modules", "foo", + "--add-reads", "foo=foo2"); + assertEquals(Collections.emptyList(), JavacParser.validateCompilerOptions(input, com.sun.tools.javac.code.Source.lookup("1.8"))); + assertEquals(input, JavacParser.validateCompilerOptions(input, com.sun.tools.javac.code.Source.lookup("9"))); + assertEquals(input, JavacParser.validateCompilerOptions(input, com.sun.tools.javac.code.Source.lookup("10"))); + } + private FileObject createFile(String path, String content) throws Exception { FileObject file = FileUtil.createData(sourceRoot, path); TestUtilities.copyStringToFile(file, content);