From: Duarte Meneses Date: Fri, 21 Aug 2015 14:41:11 +0000 (+0200) Subject: SONAR-6665 StackOverflow error when analyzing project with several modules having... X-Git-Tag: 5.2-RC1~696 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a805e4796f8826acc73f2078e7374f1956402dfd;p=sonarqube.git SONAR-6665 StackOverflow error when analyzing project with several modules having same key --- diff --git a/it/it-projects/batch/multi-module-repeated-names/modules/module1/module1/sources/Fake.java b/it/it-projects/batch/multi-module-repeated-names/modules/module1/module1/sources/Fake.java new file mode 100644 index 00000000000..e67004defc5 --- /dev/null +++ b/it/it-projects/batch/multi-module-repeated-names/modules/module1/module1/sources/Fake.java @@ -0,0 +1 @@ +class Fake {} diff --git a/it/it-projects/batch/multi-module-repeated-names/modules/module1/sources/Fake.java b/it/it-projects/batch/multi-module-repeated-names/modules/module1/sources/Fake.java new file mode 100644 index 00000000000..e67004defc5 --- /dev/null +++ b/it/it-projects/batch/multi-module-repeated-names/modules/module1/sources/Fake.java @@ -0,0 +1 @@ +class Fake {} diff --git a/it/it-projects/batch/multi-module-repeated-names/sonar-project.properties b/it/it-projects/batch/multi-module-repeated-names/sonar-project.properties new file mode 100644 index 00000000000..b1816be030b --- /dev/null +++ b/it/it-projects/batch/multi-module-repeated-names/sonar-project.properties @@ -0,0 +1,19 @@ +sonar.projectKey=com.foo.project +sonar.projectName=Foo Project +sonar.projectVersion=1.0-SNAPSHOT +sonar.projectDescription=Description of Foo Project + +sonar.sources=sources +sonar.tests=tests +sonar.binaries=target/classes + +sonar.modules=module1 + +module1.sonar.projectBaseDir=modules/module1 +module1.sonar.projectKey=com.foo.project.module1 +module1.sonar.projectName=Foo Module 1 +module1.sonar.modules=module1 + +module1.module1.sonar.projectBaseDir=module1 +module1.module1.sonar.projectKey=com.foo.project.module1.module1 +module1.module1.sonar.projectName=Foo Sub Module 1 diff --git a/it/it-tests/src/test/java/batch/suite/ProjectBuilderTest.java b/it/it-tests/src/test/java/batch/suite/ProjectBuilderTest.java index d0e9bad2dc9..f76e61414e3 100644 --- a/it/it-tests/src/test/java/batch/suite/ProjectBuilderTest.java +++ b/it/it-tests/src/test/java/batch/suite/ProjectBuilderTest.java @@ -7,6 +7,9 @@ package batch.suite; import static org.assertj.core.api.Assertions.assertThat; +import com.sonar.orchestrator.build.BuildFailureException; + +import com.sonar.orchestrator.build.SonarRunner; import util.ItUtils; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.MavenBuild; @@ -44,6 +47,18 @@ public class ProjectBuilderTest { assertThat(getResource("com.sonarsource.it.projects.batch:project-builder-module-b:src/IgnoredFile.java")).isNull(); } + @Test + // SONAR-6665 + public void errorSubModuleSameName() { + SonarRunner build = SonarRunner.create(ItUtils.projectDir("batch/multi-module-repeated-names")); + + try { + orchestrator.executeBuild(build); + } catch (BuildFailureException e) { + assertThat(e.getResult().getLogs()).contains("Two modules have the same name: module1"); + } + } + private void checkProject() { Resource project = getResource("com.sonarsource.it.projects.batch:project-builder"); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java index 7b5cd129fac..670bf714eef 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java @@ -20,7 +20,6 @@ package org.sonar.batch.scan; import org.sonar.batch.analysis.AnalysisProperties; - import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; @@ -31,11 +30,14 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -136,7 +138,7 @@ public class ProjectReactorBuilder { String prefix = !currentModuleId.isEmpty() ? currentModuleId + "." : ""; // By default all properties starting with module prefix belong to current module for (Map.Entry entry : allProperties.entrySet()) { - String key = (String) entry.getKey(); + String key = entry.getKey(); int prefixLength = prefix.length(); if (key.startsWith(prefix)) { currentModuleProperties.put(key.substring(prefixLength), entry.getValue()); @@ -147,14 +149,31 @@ public class ProjectReactorBuilder { // Sort module by reverse lexicographic order to avoid issue when one module id is a prefix of another one Collections.sort(moduleIds); Collections.reverse(moduleIds); + Map> result = new HashMap<>(); + result.put(currentModuleId, currentModuleProperties); + for (String moduleId : moduleIds) { - result.putAll(extractPropertiesByModule(moduleId, currentModuleProperties)); + Map> subModuleProps = extractPropertiesByModule(moduleId, currentModuleProperties); + checkRepeatedModuleNames(result.keySet(), subModuleProps.keySet()); + result.putAll(subModuleProps); } - result.put(currentModuleId, currentModuleProperties); return result; } + private static void checkRepeatedModuleNames(Collection currentModules, Collection modulesToMerge) { + Set union = new HashSet<>(); + union.addAll(currentModules); + union.retainAll(modulesToMerge); + if (!union.isEmpty()) { + if(union.size() > 1) { + throw new IllegalStateException(String.format("Modules have the following repeated names: %s. Each module must have a unique name.", union)); + } else { + throw new IllegalStateException(String.format("Two modules have the same name: %s. Each module must have a unique name.", union.iterator().next())); + } + } + } + protected ProjectDefinition defineRootProject(Map rootProperties, @Nullable ProjectDefinition parent) { if (rootProperties.containsKey(PROPERTY_MODULES)) { checkMandatoryProperties(rootProperties, MANDATORY_PROPERTIES_FOR_MULTIMODULE_PROJECT); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java index 9643520511c..b4bdeb07877 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java @@ -77,6 +77,14 @@ public class ProjectReactorBuilderTest { public void shouldNotFailIfBlankSourceDirectory() { loadProjectDefinition("simple-project-with-blank-source-dir"); } + + @Test + public void modulesRepeatedNames() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Two modules have the same name: module1"); + + loadProjectDefinition("multi-module-repeated-names"); + } @Test public void shouldDefineMultiModuleProjectWithDefinitionsAllInRootProject() throws IOException { diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java new file mode 100644 index 00000000000..e67004defc5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java @@ -0,0 +1 @@ +class Fake {} diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java new file mode 100644 index 00000000000..e67004defc5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java @@ -0,0 +1 @@ +class Fake {} diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties new file mode 100644 index 00000000000..b1816be030b --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties @@ -0,0 +1,19 @@ +sonar.projectKey=com.foo.project +sonar.projectName=Foo Project +sonar.projectVersion=1.0-SNAPSHOT +sonar.projectDescription=Description of Foo Project + +sonar.sources=sources +sonar.tests=tests +sonar.binaries=target/classes + +sonar.modules=module1 + +module1.sonar.projectBaseDir=modules/module1 +module1.sonar.projectKey=com.foo.project.module1 +module1.sonar.projectName=Foo Module 1 +module1.sonar.modules=module1 + +module1.module1.sonar.projectBaseDir=module1 +module1.module1.sonar.projectKey=com.foo.project.module1.module1 +module1.module1.sonar.projectName=Foo Sub Module 1