]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6665 StackOverflow error when analyzing project with several modules having...
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Fri, 21 Aug 2015 14:41:11 +0000 (16:41 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Mon, 24 Aug 2015 07:54:39 +0000 (09:54 +0200)
it/it-projects/batch/multi-module-repeated-names/modules/module1/module1/sources/Fake.java [new file with mode: 0644]
it/it-projects/batch/multi-module-repeated-names/modules/module1/sources/Fake.java [new file with mode: 0644]
it/it-projects/batch/multi-module-repeated-names/sonar-project.properties [new file with mode: 0644]
it/it-tests/src/test/java/batch/suite/ProjectBuilderTest.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java
sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java
sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties [new file with mode: 0644]

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 (file)
index 0000000..e67004d
--- /dev/null
@@ -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 (file)
index 0000000..e67004d
--- /dev/null
@@ -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 (file)
index 0000000..b1816be
--- /dev/null
@@ -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
index d0e9bad2dc90d4f23198ac256979c01124df6fc0..f76e61414e349728ba6426aa5d7b58076469d4e6 100644 (file)
@@ -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");
 
index 7b5cd129fac42402f4922cb4e123ee0e78ddc211..670bf714eef8be8ee8b211b2790ac57eac219345 100644 (file)
@@ -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<String, String> 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<String, Map<String, String>> result = new HashMap<>();
+    result.put(currentModuleId, currentModuleProperties);
+    
     for (String moduleId : moduleIds) {
-      result.putAll(extractPropertiesByModule(moduleId, currentModuleProperties));
+      Map<String, Map<String, String>> subModuleProps = extractPropertiesByModule(moduleId, currentModuleProperties);
+      checkRepeatedModuleNames(result.keySet(), subModuleProps.keySet());
+      result.putAll(subModuleProps);
     }
-    result.put(currentModuleId, currentModuleProperties);
     return result;
   }
 
+  private static void checkRepeatedModuleNames(Collection<String> currentModules, Collection<String> modulesToMerge) {
+    Set<String> 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<String, String> rootProperties, @Nullable ProjectDefinition parent) {
     if (rootProperties.containsKey(PROPERTY_MODULES)) {
       checkMandatoryProperties(rootProperties, MANDATORY_PROPERTIES_FOR_MULTIMODULE_PROJECT);
index 9643520511cc5d522b34bd2e62c6b3f60d4ef123..b4bdeb07877b7388e636e0c95877423ef207104e 100644 (file)
@@ -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 (file)
index 0000000..e67004d
--- /dev/null
@@ -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 (file)
index 0000000..e67004d
--- /dev/null
@@ -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 (file)
index 0000000..b1816be
--- /dev/null
@@ -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