diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java index 5f000daa8a..be0f96d247 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java @@ -73,6 +73,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static java.util.Arrays.asList; import static java.util.ServiceLoader.load; @@ -346,7 +347,9 @@ public class ExtensionLoader { checkDestroyed(); // solve the bug of using @SPI's wrapper method to report a null pointer exception. Map, T> activateExtensionsMap = new TreeMap<>(activateComparator); - List names = values == null ? new ArrayList<>(0) : asList(values); + List names = values == null ? + new ArrayList<>(0) : + Arrays.stream(values).map(StringUtils::trim).collect(Collectors.toList()); Set namesSet = new HashSet<>(names); if (!namesSet.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) { if (cachedActivateGroups.size() == 0) { diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java index 4f8f1474f1..2e2b2a0884 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java @@ -221,7 +221,7 @@ class ExtensionLoaderTest { } @Test - void test_getActivateExtension_WithWrapper() { + void test_getActivateExtension_WithWrapper1() { URL url = URL.valueOf("test://localhost/test"); List list = getExtensionLoader(ActivateExt1.class) .getActivateExtension(url, new String[]{}, "order"); @@ -596,7 +596,7 @@ class ExtensionLoaderTest { } @Test - void testLoadDefaultActivateExtension() { + void testLoadDefaultActivateExtension1() { // test default URL url = URL.valueOf("test://localhost/test?ext=order1,default"); List list = getExtensionLoader(ActivateExt1.class) @@ -620,6 +620,31 @@ class ExtensionLoaderTest { assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); } + @Test + void testLoadDefaultActivateExtension2() { + // test default + URL url = URL.valueOf("test://localhost/test?ext=order1 , default"); + List list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class); + assertSame(list.get(1).getClass(), ActivateExt1Impl1.class); + + url = URL.valueOf("test://localhost/test?ext=default, order1"); + list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), ActivateExt1Impl1.class); + assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); + + url = URL.valueOf("test://localhost/test?ext=order1"); + list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), ActivateExt1Impl1.class); + assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); + } + @Test void testInjectExtension() { // register bean for test ScopeBeanExtensionInjector diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java index 70380568ef..4e9c20d415 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java @@ -670,8 +670,9 @@ public class ConfigValidationUtils { if (isNotEmpty(value)) { String[] values = value.split("\\s*[,]+\\s*"); for (String v : values) { + v = StringUtils.trim(v); if (v.startsWith(REMOVE_VALUE_PREFIX)) { - v = v.substring(1); + continue; } if (DEFAULT_KEY.equals(v)) { continue; diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java index 0a811bbae5..1a986a5884 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java @@ -207,8 +207,25 @@ class AbstractConfigTest { @Test void checkMultiExtension2() { + try { + ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world"); + } catch (Throwable t) { + Assertions.fail(t); + } + } + @Test + void checkMultiExtension3() { Assertions.assertThrows(IllegalStateException.class, - () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world")); + () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , world")); + } + + @Test + void checkMultiExtension4() { + try { + ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , -world "); + } catch (Throwable t) { + Assertions.fail(t); + } } @Test