From d0cc88391f1a45ee753f9a93b16f0f4dbe10ce9c Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 2 Feb 2022 13:38:24 -0600 Subject: [PATCH] SONAR-15966 Fix Spring bean names to include classloader --- .../java/org/sonar/core/platform/ComponentKeys.java | 6 +++++- .../org/sonar/core/platform/ComponentKeysTest.java | 11 ++++++++--- .../scanner/bootstrap/SpringComponentContainer.java | 12 ++++-------- .../bootstrap/SpringComponentContainerTest.java | 10 +++++++--- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java index 81a1b822b9d..59b1ab6bd15 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java @@ -46,6 +46,10 @@ public class ComponentKeys { return ofInstance(component, LOG); } + public String ofClass(Class clazz) { + return clazz.getClassLoader() + "-" + clazz.getCanonicalName(); + } + String ofInstance(Object component, Logger log) { String key = component.toString(); if (IDENTITY_HASH_PATTERN.matcher(key).matches()) { @@ -54,6 +58,6 @@ public class ComponentKeys { } key += Uuids.create(); } - return component.getClass().getCanonicalName() + "-" + key; + return ofClass(component.getClass()) + "-" + key; } } diff --git a/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java index 8413cb8ed38..5dd30052181 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java @@ -33,13 +33,18 @@ public class ComponentKeysTest { ComponentKeys keys = new ComponentKeys(); @Test - public void generate_key_of_class() { + public void generate_key_of_object() { assertThat(keys.of(FakeComponent.class)).isEqualTo(FakeComponent.class); } @Test - public void generate_key_of_object() { - assertThat(keys.of(new FakeComponent())).isEqualTo("org.sonar.core.platform.ComponentKeysTest.FakeComponent-fake"); + public void generate_key_of_instance() { + assertThat((String) keys.of(new FakeComponent())).endsWith("-org.sonar.core.platform.ComponentKeysTest.FakeComponent-fake"); + } + + @Test + public void generate_key_of_class() { + assertThat(keys.ofClass(FakeComponent.class)).endsWith("-org.sonar.core.platform.ComponentKeysTest.FakeComponent"); } @Test diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java index 0e1a3ad9d31..17325193d5b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringComponentContainer.java @@ -20,7 +20,6 @@ package org.sonar.scanner.bootstrap; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -33,7 +32,6 @@ import org.sonar.core.platform.Container; import org.sonar.core.platform.ExtensionContainer; import org.sonar.core.platform.PluginInfo; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator; import static java.util.Collections.emptyList; import static java.util.Optional.ofNullable; @@ -62,8 +60,6 @@ public class SpringComponentContainer implements ExtensionContainer { this.parent = parent; this.propertyDefinitions = propertyDefinitions; this.context = new AnnotationConfigApplicationContext(new PriorityBeanFactory()); - // it won't set the name of beans created with @Bean annotated methods - this.context.setBeanNameGenerator(new FullyQualifiedAnnotationBeanNameGenerator()); if (parent != null) { context.setParent(parent.context); } @@ -76,8 +72,8 @@ public class SpringComponentContainer implements ExtensionContainer { /** * Beans need to have a unique name, otherwise they'll override each other. * The strategy is: - * - For classes, use the fully qualified class name as the name of the bean - * - For instances, use the FQCN + toString() + * - For classes, use the classloader + fully qualified class name as the name of the bean + * - For instances, use the Classloader + FQCN + toString() * - If the object is a collection, iterate through the elements and apply the same strategy for each of them */ @Override @@ -85,7 +81,7 @@ public class SpringComponentContainer implements ExtensionContainer { for (Object o : objects) { if (o instanceof Class) { Class clazz = (Class) o; - context.registerBean(clazz); + context.registerBean(componentKeys.ofClass(clazz), clazz); } else if (o instanceof Iterable) { add(Iterables.toArray((Iterable) o, Object.class)); } else { @@ -111,7 +107,7 @@ public class SpringComponentContainer implements ExtensionContainer { if (o instanceof Class) { Class clazz = (Class) o; ClassDerivedBeanDefinition bd = new ClassDerivedBeanDefinition(clazz); - context.registerBeanDefinition(clazz.getName(), bd); + context.registerBeanDefinition(componentKeys.ofClass(clazz), bd); } else if (o instanceof Iterable) { ((Iterable) o).forEach(this::addExtension); } else { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java index bbc00cf338a..7c1008b4938 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/SpringComponentContainerTest.java @@ -55,16 +55,20 @@ public class SpringComponentContainerTest { SpringComponentContainer container = new SimpleContainer(new ToString("a"), new ToString("b")); container.startComponents(); assertThat(container.context.getBeanDefinitionNames()) - .contains("org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-a", "org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-b"); + .contains( + this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-a", + this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.ToString-b"); assertThat(container.getComponentsByType(ToString.class)).hasSize(2); } @Test - public void register_class_with_fqcn() { + public void register_class_with_classloader_and_fqcn() { SpringComponentContainer container = new SimpleContainer(A.class, B.class); container.startComponents(); assertThat(container.context.getBeanDefinitionNames()) - .contains("org.sonar.scanner.bootstrap.SpringComponentContainerTest$A", "org.sonar.scanner.bootstrap.SpringComponentContainerTest$B"); + .contains( + this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.A", + this.getClass().getClassLoader() + "-org.sonar.scanner.bootstrap.SpringComponentContainerTest.B"); assertThat(container.getComponentByType(A.class)).isNotNull(); assertThat(container.getComponentByType(B.class)).isNotNull(); } -- 2.39.5