diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java index 06d33cb5eff..c54624df93e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java @@ -95,7 +95,7 @@ private void loadMigrationRule() { path = CommonConstants.DEFAULT_DUBBO_MIGRATION_FILE; } } - this.localMigrationRule = ConfigUtils.loadMigrationRule(path); + this.localMigrationRule = ConfigUtils.loadMigrationRule(applicationModel.getClassLoaders(), path); } @Deprecated @@ -313,4 +313,9 @@ public String getLocalMigrationRule() { return localMigrationRule; } + public void refreshClassLoaders() { + propertiesConfiguration.refresh(); + loadMigrationRule(); + } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java index efc6bb21fc0..5e9b881a6e0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java @@ -31,7 +31,17 @@ */ public class PropertiesConfiguration implements Configuration { + private Properties properties; + private final ApplicationModel applicationModel; + public PropertiesConfiguration(ApplicationModel applicationModel) { + this.applicationModel = applicationModel; + refresh(); + } + + public void refresh() { + //load the default properties + properties = ConfigUtils.getProperties(applicationModel.getClassLoaders()); ExtensionLoader propertiesProviderExtensionLoader = applicationModel.getExtensionLoader(OrderedPropertiesProvider.class); Set propertiesProviderNames = propertiesProviderExtensionLoader.getSupportedExtensions(); @@ -48,23 +58,38 @@ public PropertiesConfiguration(ApplicationModel applicationModel) { return b.priority() - a.priority(); }); - //load the default properties - Properties properties = ConfigUtils.getProperties(); //override the properties. for (OrderedPropertiesProvider orderedPropertiesProvider : - orderedPropertiesProviders) { + orderedPropertiesProviders) { properties.putAll(orderedPropertiesProvider.initProperties()); } + } + @Override + public String getProperty(String key) { + return properties.getProperty(key); } @Override public Object getInternalProperty(String key) { - return ConfigUtils.getProperty(key); + return properties.getProperty(key); + } + + public void setProperty(String key, String value) { + properties.setProperty(key, value); + } + + public String remove(String key) { + return (String) properties.remove(key); + } + + @Deprecated + public void setProperties(Properties properties) { + this.properties = properties; } public Map getProperties() { - return (Map) ConfigUtils.getProperties(); + return (Map) properties; } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java index 07d8cdee982..d65228a1584 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.common.extension; +import org.apache.dubbo.rpc.model.ScopeModel; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -34,10 +36,12 @@ public class ExtensionDirector implements ExtensionAccessor { private ExtensionDirector parent; private final ExtensionScope scope; private List extensionPostProcessors = new ArrayList<>(); + private ScopeModel scopeModel; - public ExtensionDirector(ExtensionDirector parent, ExtensionScope scope) { + public ExtensionDirector(ExtensionDirector parent, ExtensionScope scope, ScopeModel scopeModel) { this.parent = parent; this.scope = scope; + this.scopeModel = scopeModel; } public void addExtensionPostProcessor(ExtensionPostProcessor processor) { @@ -107,7 +111,7 @@ private ExtensionLoader createExtensionLoader(Class type) { private ExtensionLoader createExtensionLoader0(Class type) { ExtensionLoader loader; - extensionLoadersMap.putIfAbsent(type, new ExtensionLoader(type, this)); + extensionLoadersMap.putIfAbsent(type, new ExtensionLoader(type, this, scopeModel)); loader = (ExtensionLoader) extensionLoadersMap.get(type); return loader; } @@ -124,4 +128,8 @@ private static boolean withExtensionAnnotation(Class type) { public ExtensionDirector getParent() { return parent; } + + public void removeAllCachedLoader() { + // extensionLoadersMap.clear(); + } } 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 c77ea587225..760cfb3854c 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 @@ -37,6 +37,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; +import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ScopeModelAccessor; import java.io.BufferedReader; @@ -130,6 +131,7 @@ public class ExtensionLoader { private InstantiationStrategy instantiationStrategy; private Environment environment; private ActivateComparator activateComparator; + private ScopeModel scopeModel; public static void setLoadingStrategies(LoadingStrategy... strategies) { if (ArrayUtils.isNotEmpty(strategies)) { @@ -161,7 +163,7 @@ public static List getLoadingStrategies() { return asList(strategies); } - ExtensionLoader(Class type, ExtensionDirector extensionDirector) { + ExtensionLoader(Class type, ExtensionDirector extensionDirector, ScopeModel scopeModel) { this.type = type; this.extensionDirector = extensionDirector; this.extensionPostProcessors = extensionDirector.getExtensionPostProcessors(); @@ -169,6 +171,7 @@ public static List getLoadingStrategies() { this.injector = (type == ExtensionInjector.class ? null : extensionDirector.getExtensionLoader(ExtensionInjector.class) .getAdaptiveExtension()); this.activateComparator = new ActivateComparator(extensionDirector); + this.scopeModel = scopeModel; } private void initInstantiationStrategy() { @@ -917,29 +920,28 @@ private void loadDirectory(Map> extensionClasses, String dir, S boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) { String fileName = dir + type; try { - Enumeration urls = null; - ClassLoader classLoader = findClassLoader(); + + Enumeration urls; // try to load from ExtensionLoader's ClassLoader first if (extensionLoaderClassLoaderFirst) { ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader(); if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) { urls = extensionLoaderClassLoader.getResources(fileName); + loadFromClass(extensionClasses, overridden, urls, extensionLoaderClassLoader, excludedPackages); } } - if (urls == null || !urls.hasMoreElements()) { - if (classLoader != null) { - urls = classLoader.getResources(fileName); - } else { - urls = ClassLoader.getSystemResources(fileName); - } - } + // load from scope model + Set classLoaders = scopeModel.getClassLoaders(); - if (urls != null) { - while (urls.hasMoreElements()) { - java.net.URL resourceURL = urls.nextElement(); - loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages); + if (CollectionUtils.isEmpty(classLoaders)) { + urls = ClassLoader.getSystemResources(fileName); + loadFromClass(extensionClasses, overridden, urls, null, excludedPackages); + } else { + for (ClassLoader classLoader : classLoaders) { + urls = classLoader.getResources(fileName); + loadFromClass(extensionClasses, overridden, urls, classLoader, excludedPackages); } } } catch (Throwable t) { @@ -948,6 +950,15 @@ private void loadDirectory(Map> extensionClasses, String dir, S } } + private void loadFromClass(Map> extensionClasses, boolean overridden, Enumeration urls, ClassLoader classLoader, String[] excludedPackages) { + if (urls != null) { + while (urls.hasMoreElements()) { + java.net.URL resourceURL = urls.nextElement(); + loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages); + } + } + } + private void loadResource(Map> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL, boolean overridden, String... excludedPackages) { try { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java index 5a55ce27868..17d1b8453de 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java @@ -19,7 +19,7 @@ import org.apache.dubbo.common.config.Configuration; import org.apache.dubbo.common.config.InmemoryConfiguration; import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.common.extension.ExtensionDirector; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -34,9 +34,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,8 +50,7 @@ public class ConfigUtils { private static final Logger logger = LoggerFactory.getLogger(ConfigUtils.class); private static Pattern VARIABLE_PATTERN = Pattern.compile( - "\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?"); - private static volatile Properties PROPERTIES; + "\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?"); private static int PID = -1; private ConfigUtils() { @@ -61,15 +62,15 @@ public static boolean isNotEmpty(String value) { public static boolean isEmpty(String value) { return StringUtils.isEmpty(value) - || "false".equalsIgnoreCase(value) - || "0".equalsIgnoreCase(value) - || "null".equalsIgnoreCase(value) - || "N/A".equalsIgnoreCase(value); + || "false".equalsIgnoreCase(value) + || "0".equalsIgnoreCase(value) + || "null".equalsIgnoreCase(value) + || "N/A".equalsIgnoreCase(value); } public static boolean isDefault(String value) { return "true".equalsIgnoreCase(value) - || "default".equalsIgnoreCase(value); + || "default".equalsIgnoreCase(value); } /** @@ -85,11 +86,11 @@ public static boolean isDefault(String value) { * @param def Default extension list * @return result extension list */ - public static List mergeValues(Class type, String cfg, List def) { + public static List mergeValues(ExtensionDirector extensionDirector, Class type, String cfg, List def) { List defaults = new ArrayList(); if (def != null) { for (String name : def) { - if (ExtensionLoader.getExtensionLoader(type).hasExtension(name)) { + if (extensionDirector.getExtensionLoader(type).hasExtension(name)) { defaults.add(name); } } @@ -159,60 +160,18 @@ public static String replaceProperty(String expression, Configuration configurat /** * Get dubbo properties. * It is not recommended to use this method to modify dubbo properties. + * * @return */ - public static Properties getProperties() { - //TODO remove global instance PROPERTIES from ConfigUtils - if (PROPERTIES == null) { - synchronized (ConfigUtils.class) { - if (PROPERTIES == null) { - String path = System.getProperty(CommonConstants.DUBBO_PROPERTIES_KEY); - if (path == null || path.length() == 0) { - path = System.getenv(CommonConstants.DUBBO_PROPERTIES_KEY); - if (path == null || path.length() == 0) { - path = CommonConstants.DEFAULT_DUBBO_PROPERTIES; - } - } - PROPERTIES = ConfigUtils.loadProperties(path, false, true); - } + public static Properties getProperties(Set classLoaders) { + String path = System.getProperty(CommonConstants.DUBBO_PROPERTIES_KEY); + if (path == null || path.length() == 0) { + path = System.getenv(CommonConstants.DUBBO_PROPERTIES_KEY); + if (path == null || path.length() == 0) { + path = CommonConstants.DEFAULT_DUBBO_PROPERTIES; } } - return PROPERTIES; - } - - /** - * This method should be called before Dubbo starting. - * It is not recommended to use this method to modify dubbo properties. - */ - public static void setProperties(Properties properties) { - PROPERTIES = properties; - } - - /** - * This method should be called before Dubbo starting. - * It is not recommended to use this method to modify dubbo properties. - */ - public static void addProperties(Properties properties) { - if (properties != null) { - getProperties().putAll(properties); - } - } - - public static String getProperty(String key) { - return getProperty(key, null); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public static String getProperty(String key, String defaultValue) { - String value = System.getProperty(key); - if (value != null && value.length() > 0) { - return value; - } - return getProperty(getProperties(), key, defaultValue); - } - - public static String getProperty(Properties properties, String key, String defaultValue) { - return replaceProperty(properties.getProperty(key, defaultValue), (Map) properties); + return ConfigUtils.loadProperties(classLoaders, path, false, true); } /** @@ -229,12 +188,12 @@ public static String getSystemProperty(String key) { return value; } - public static Properties loadProperties(String fileName) { - return loadProperties(fileName, false, false); + public static Properties loadProperties(Set classLoaders, String fileName) { + return loadProperties(classLoaders, fileName, false, false); } - public static Properties loadProperties(String fileName, boolean allowMultiFile) { - return loadProperties(fileName, allowMultiFile, false); + public static Properties loadProperties(Set classLoaders, String fileName, boolean allowMultiFile) { + return loadProperties(classLoaders, fileName, allowMultiFile, false); } /** @@ -249,7 +208,7 @@ public static Properties loadProperties(String fileName, boolean allowMultiFile) * * @throws IllegalStateException not allow multi-file, but multi-file exist on class path. */ - public static Properties loadProperties(String fileName, boolean allowMultiFile, boolean optional) { + public static Properties loadProperties(Set classLoaders, String fileName, boolean allowMultiFile, boolean optional) { Properties properties = new Properties(); // add scene judgement in windows environment Fix 2557 if (checkFileNameExist(fileName)) { @@ -266,18 +225,23 @@ public static Properties loadProperties(String fileName, boolean allowMultiFile, return properties; } - List list = new ArrayList(); + Set set = new HashSet(); try { Enumeration urls = ClassUtils.getClassLoader().getResources(fileName); - list = new ArrayList(); while (urls.hasMoreElements()) { - list.add(urls.nextElement()); + set.add(urls.nextElement()); + } + for (ClassLoader classLoader : classLoaders) { + urls = classLoader.getResources(fileName); + while (urls.hasMoreElements()) { + set.add(urls.nextElement()); + } } } catch (Throwable t) { logger.warn("Fail to load " + fileName + " file: " + t.getMessage(), t); } - if (list.isEmpty()) { + if (set.isEmpty()) { if (!optional) { logger.warn("No " + fileName + " found on the class path."); } @@ -285,9 +249,9 @@ public static Properties loadProperties(String fileName, boolean allowMultiFile, } if (!allowMultiFile) { - if (list.size() > 1) { + if (set.size() > 1) { String errMsg = String.format("only 1 %s file is expected, but %d dubbo.properties files found on class path: %s", - fileName, list.size(), list.toString()); + fileName, set.size(), set.toString()); logger.warn(errMsg); } @@ -300,9 +264,9 @@ public static Properties loadProperties(String fileName, boolean allowMultiFile, return properties; } - logger.info("load " + fileName + " properties file from " + list); + logger.info("load " + fileName + " properties file from " + set); - for (java.net.URL url : list) { + for (java.net.URL url : set) { try { Properties p = new Properties(); InputStream input = url.openStream(); @@ -325,23 +289,28 @@ public static Properties loadProperties(String fileName, boolean allowMultiFile, return properties; } - public static String loadMigrationRule(String fileName) { + public static String loadMigrationRule(Set classLoaders, String fileName) { String rawRule = ""; if (checkFileNameExist(fileName)) { try { try (FileInputStream input = new FileInputStream(fileName)) { - rawRule = readString(input); + return readString(input); } } catch (Throwable e) { logger.warn("Failed to load " + fileName + " file from " + fileName + "(ignore this file): " + e.getMessage(), e); } - return rawRule; } try { InputStream is = ClassUtils.getClassLoader().getResourceAsStream(fileName); if (is != null) { - rawRule = readString(is); + return readString(is); + } + for (ClassLoader classLoader : classLoaders) { + is = classLoader.getResourceAsStream(fileName); + if (is != null) { + return readString(is); + } } } catch (Throwable e) { logger.warn("Failed to load " + fileName + " file from " + fileName + "(ignore this file): " + e.getMessage(), e); @@ -352,7 +321,7 @@ public static String loadMigrationRule(String fileName) { private static String readString(InputStream is) { StringBuilder stringBuilder = new StringBuilder(); char[] buffer = new char[10]; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))){ + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { int n; while ((n = reader.read(buffer)) != -1) { if (n < 10) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java index 889ada1a852..cd307371b4c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.common.utils; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -73,7 +74,7 @@ public class PojoUtils { private static final Logger logger = LoggerFactory.getLogger(PojoUtils.class); private static final ConcurrentMap NAME_METHODS_CACHE = new ConcurrentHashMap(); private static final ConcurrentMap, ConcurrentMap> CLASS_FIELD_CACHE = new ConcurrentHashMap, ConcurrentMap>(); - private static final boolean GENERIC_WITH_CLZ = Boolean.parseBoolean(ConfigUtils.getProperty(CommonConstants.GENERIC_WITH_CLZ_KEY, "true")); + private static final boolean GENERIC_WITH_CLZ = Boolean.parseBoolean(ConfigurationUtils.getProperty(CommonConstants.GENERIC_WITH_CLZ_KEY, "true")); private static final List> CLASS_CAN_BE_STRING = Arrays.asList(Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Boolean.class, Character.class); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java index 9ec18fb8e8b..a08d39b020e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; /** * {@link ExtensionLoader}, {@code DubboBootstrap} and this class are at present designed to be @@ -48,15 +49,16 @@ public class ApplicationModel extends ScopeModel { protected static final Logger LOGGER = LoggerFactory.getLogger(ApplicationModel.class); - public static final String NAME = "application"; + private static final AtomicLong index = new AtomicLong(0); + public static final String NAME = "ApplicationModel"; private static volatile ApplicationModel defaultInstance; - private volatile List moduleModels = Collections.synchronizedList(new ArrayList<>()); + private final List moduleModels = Collections.synchronizedList(new ArrayList<>()); private Environment environment; private ConfigManager configManager; private ServiceRepository serviceRepository; - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; private ModuleModel internalModule; @@ -153,12 +155,13 @@ public ApplicationModel(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; frameworkModel.addApplication(this); initialize(); + this.modelName = NAME + "-" + index.getAndIncrement(); } @Override protected void initialize() { super.initialize(); - internalModule = new ModuleModel(this); + internalModule = new ModuleModel(this.modelName + "-internal", this); this.serviceRepository = new ServiceRepository(this); ExtensionLoader extensionLoader = this.getExtensionLoader(ApplicationInitListener.class); @@ -299,7 +302,18 @@ public void setServiceRepository(ServiceRepository serviceRepository) { } @Override - public String toString() { - return "ApplicationModel"; + public void addClassLoader(ClassLoader classLoader) { + super.addClassLoader(classLoader); + if (environment != null) { + environment.refreshClassLoaders(); + } + } + + @Override + public void removeClassLoader(ClassLoader classLoader) { + super.removeClassLoader(classLoader); + if (environment != null) { + environment.refreshClassLoaders(); + } } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java index 1948298bb82..a23386eb591 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; /** * Model of dubbo framework, it can be shared with multiple applications. @@ -33,6 +34,8 @@ public class FrameworkModel extends ScopeModel { protected static final Logger LOGGER = LoggerFactory.getLogger(FrameworkModel.class); + private static final AtomicLong index = new AtomicLong(0); + public static final String NAME = "FrameworkModel"; private volatile static FrameworkModel defaultInstance; private static List allInstances = Collections.synchronizedList(new ArrayList<>()); @@ -45,6 +48,7 @@ public class FrameworkModel extends ScopeModel { public FrameworkModel() { super(null, ExtensionScope.FRAMEWORK); initialize(); + this.modelName = NAME + "-" + index.getAndIncrement(); } @Override @@ -120,9 +124,4 @@ public List getApplicationModels() { public FrameworkServiceRepository getServiceRepository() { return serviceRepository; } - - @Override - public String toString() { - return "FrameworkModel"; - } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java index 5067589fc1c..494a9879339 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; /** * Model of a service module @@ -30,15 +31,22 @@ public class ModuleModel extends ScopeModel { private static final Logger logger = LoggerFactory.getLogger(ModuleModel.class); - private String id; + private static final AtomicLong index = new AtomicLong(0); + public static final String NAME = "ModuleModel"; + private final ApplicationModel applicationModel; private ModuleServiceRepository serviceRepository; public ModuleModel(ApplicationModel applicationModel) { + this(NAME + "-" + index.getAndIncrement(), applicationModel); + } + + public ModuleModel(String name, ApplicationModel applicationModel) { super(applicationModel, ExtensionScope.MODULE); this.applicationModel = applicationModel; applicationModel.addModule(this); initialize(); + this.modelName = name; } @Override @@ -101,17 +109,4 @@ public ApplicationModel getApplicationModel() { public ModuleServiceRepository getServiceRepository() { return serviceRepository; } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - @Override - public String toString() { - return "ModuleModel"; - } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java index 6cef351672e..aec14b7ea2c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java @@ -20,7 +20,9 @@ import org.apache.dubbo.common.extension.ExtensionAccessor; import org.apache.dubbo.common.extension.ExtensionDirector; import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.utils.ConcurrentHashSet; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -29,6 +31,9 @@ public abstract class ScopeModel implements ExtensionAccessor { + protected String modelName; + private Set classLoaders; + private final ScopeModel parent; private final ExtensionScope scope; @@ -54,11 +59,18 @@ public ScopeModel(ScopeModel parent, ExtensionScope scope) { * */ protected void initialize() { - this.extensionDirector = new ExtensionDirector(parent != null ? parent.getExtensionDirector() : null, scope); + this.extensionDirector = new ExtensionDirector(parent != null ? parent.getExtensionDirector() : null, scope, this); this.extensionDirector.addExtensionPostProcessor(new ScopeModelAwareExtensionProcessor(this)); this.beanFactory = new ScopeBeanFactory(parent != null ? parent.getBeanFactory() : null, extensionDirector); this.destroyListeners = new LinkedList<>(); this.attribute = new ConcurrentHashMap<>(); + this.classLoaders = new ConcurrentHashSet<>(); + + // Add Framework's ClassLoader by default + ClassLoader dubboClassLoader = ScopeModel.class.getClassLoader(); + if (dubboClassLoader != null) { + this.addClassLoader(dubboClassLoader); + } } public void destroy() { @@ -94,4 +106,32 @@ protected void postProcessAfterCreated() { processor.postProcessScopeModel(this); } } + + public String getModelName() { + return modelName; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + + public void addClassLoader(ClassLoader classLoader) { + this.classLoaders.add(classLoader); + if (parent != null) { + parent.addClassLoader(classLoader); + } + extensionDirector.removeAllCachedLoader(); + } + + public void removeClassLoader(ClassLoader classLoader) { + this.classLoaders.remove(classLoader); + if (parent != null) { + parent.removeClassLoader(classLoader); + } + extensionDirector.removeAllCachedLoader(); + } + + public Set getClassLoaders() { + return Collections.unmodifiableSet(classLoaders); + } } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java index 5a4093637ed..0a68d066f20 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java @@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -48,9 +49,9 @@ public void testInheritanceAndScope() { // 2. Child ExtensionDirector can get extension instance from parent // 3. Parent ExtensionDirector can't get extension instance from child - ExtensionDirector fwExtensionDirector = new ExtensionDirector(null, ExtensionScope.FRAMEWORK); - ExtensionDirector appExtensionDirector = new ExtensionDirector(fwExtensionDirector, ExtensionScope.APPLICATION); - ExtensionDirector moduleExtensionDirector = new ExtensionDirector(appExtensionDirector, ExtensionScope.MODULE); + ExtensionDirector fwExtensionDirector = new ExtensionDirector(null, ExtensionScope.FRAMEWORK, FrameworkModel.defaultModel()); + ExtensionDirector appExtensionDirector = new ExtensionDirector(fwExtensionDirector, ExtensionScope.APPLICATION, ApplicationModel.defaultModel()); + ExtensionDirector moduleExtensionDirector = new ExtensionDirector(appExtensionDirector, ExtensionScope.MODULE, ApplicationModel.defaultModel().getDefaultModule()); // test module extension loader FooFrameworkService testFwSrvFromModule = moduleExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName); diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ConfigUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ConfigUtilsTest.java index 149ad6c71cd..76f697768a3 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ConfigUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ConfigUtilsTest.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.config.InmemoryConfiguration; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.threadpool.ThreadPool; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -40,14 +41,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class ConfigUtilsTest { + private Properties properties; + @BeforeEach public void setUp() throws Exception { - ConfigUtils.setProperties(null); + properties = ConfigUtils.getProperties(Collections.emptySet()); } @AfterEach public void tearDown() throws Exception { - ConfigUtils.setProperties(null); } @Test @@ -78,27 +80,27 @@ public void testIsDefault() throws Exception { @Test public void testMergeValues() { - List merged = ConfigUtils.mergeValues(ThreadPool.class, "aaa,bbb,default.custom", + List merged = ConfigUtils.mergeValues(ApplicationModel.defaultModel().getExtensionDirector(), ThreadPool.class, "aaa,bbb,default.custom", asList("fixed", "default.limited", "cached")); assertEquals(asList("fixed", "cached", "aaa", "bbb", "default.custom"), merged); } @Test public void testMergeValuesAddDefault() { - List merged = ConfigUtils.mergeValues(ThreadPool.class, "aaa,bbb,default,zzz", + List merged = ConfigUtils.mergeValues(ApplicationModel.defaultModel().getExtensionDirector(), ThreadPool.class, "aaa,bbb,default,zzz", asList("fixed", "default.limited", "cached")); assertEquals(asList("aaa", "bbb", "fixed", "cached", "zzz"), merged); } @Test public void testMergeValuesDeleteDefault() { - List merged = ConfigUtils.mergeValues(ThreadPool.class, "-default", asList("fixed", "default.limited", "cached")); + List merged = ConfigUtils.mergeValues(ApplicationModel.defaultModel().getExtensionDirector(), ThreadPool.class, "-default", asList("fixed", "default.limited", "cached")); assertEquals(Collections.emptyList(), merged); } @Test public void testMergeValuesDeleteDefault_2() { - List merged = ConfigUtils.mergeValues(ThreadPool.class, "-default,aaa", asList("fixed", "default.limited", "cached")); + List merged = ConfigUtils.mergeValues(ApplicationModel.defaultModel().getExtensionDirector(), ThreadPool.class, "-default,aaa", asList("fixed", "default.limited", "cached")); assertEquals(asList("aaa"), merged); } @@ -107,7 +109,7 @@ public void testMergeValuesDeleteDefault_2() { */ @Test public void testMergeValuesDelete() { - List merged = ConfigUtils.mergeValues(ThreadPool.class, "-fixed,aaa", asList("fixed", "default.limited", "cached")); + List merged = ConfigUtils.mergeValues(ApplicationModel.defaultModel().getExtensionDirector(), ThreadPool.class, "-fixed,aaa", asList("fixed", "default.limited", "cached")); assertEquals(asList("cached", "aaa"), merged); } @@ -145,7 +147,7 @@ public void testReplaceProperty2() { public void testGetProperties1() throws Exception { try { System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, "properties.load"); - Properties p = ConfigUtils.getProperties(); + Properties p = ConfigUtils.getProperties(Collections.emptySet()); assertThat((String) p.get("a"), equalTo("12")); assertThat((String) p.get("b"), equalTo("34")); assertThat((String) p.get("c"), equalTo("56")); @@ -157,46 +159,28 @@ public void testGetProperties1() throws Exception { @Test public void testGetProperties2() throws Exception { System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY); - Properties p = ConfigUtils.getProperties(); + Properties p = ConfigUtils.getProperties(Collections.emptySet()); assertThat((String) p.get("dubbo"), equalTo("properties")); } - @Test - public void testAddProperties() throws Exception { - Properties p = new Properties(); - p.put("key1", "value1"); - ConfigUtils.addProperties(p); - assertThat((String) ConfigUtils.getProperties().get("key1"), equalTo("value1")); - } - @Test public void testLoadPropertiesNoFile() throws Exception { - Properties p = ConfigUtils.loadProperties("notExisted", true); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "notExisted", true); Properties expected = new Properties(); assertEquals(expected, p); - p = ConfigUtils.loadProperties("notExisted", false); + p = ConfigUtils.loadProperties(Collections.emptySet(), "notExisted", false); assertEquals(expected, p); } @Test public void testGetProperty() throws Exception { - assertThat(ConfigUtils.getProperty("dubbo"), equalTo("properties")); + assertThat(properties.getProperty("dubbo"), equalTo("properties")); } @Test public void testGetPropertyDefaultValue() throws Exception { - assertThat(ConfigUtils.getProperty("not-exist", "default"), equalTo("default")); - } - - @Test - public void testGetPropertyFromSystem() throws Exception { - try { - System.setProperty("dubbo", "system"); - assertThat(ConfigUtils.getProperty("dubbo"), equalTo("system")); - } finally { - System.clearProperty("dubbo"); - } + assertThat(properties.getProperty("not-exist", "default"), equalTo("default")); } @Test @@ -211,13 +195,13 @@ public void testGetSystemProperty() throws Exception { @Test public void testLoadProperties() throws Exception { - Properties p = ConfigUtils.loadProperties("dubbo.properties"); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "dubbo.properties"); assertThat((String)p.get("dubbo"), equalTo("properties")); } @Test public void testLoadPropertiesOneFile() throws Exception { - Properties p = ConfigUtils.loadProperties("properties.load", false); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "properties.load", false); Properties expected = new Properties(); expected.put("a", "12"); @@ -229,7 +213,7 @@ public void testLoadPropertiesOneFile() throws Exception { @Test public void testLoadPropertiesOneFileAllowMulti() throws Exception { - Properties p = ConfigUtils.loadProperties("properties.load", true); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "properties.load", true); Properties expected = new Properties(); expected.put("a", "12"); @@ -241,7 +225,7 @@ public void testLoadPropertiesOneFileAllowMulti() throws Exception { @Test public void testLoadPropertiesOneFileNotRootPath() throws Exception { - Properties p = ConfigUtils.loadProperties("META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool", false); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool", false); Properties expected = new Properties(); expected.put("fixed", "org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool"); @@ -257,7 +241,7 @@ public void testLoadPropertiesOneFileNotRootPath() throws Exception { @Test public void testLoadPropertiesMultiFileNotRootPathException() throws Exception { try { - ConfigUtils.loadProperties("META-INF/services/org.apache.dubbo.common.status.StatusChecker", false); + ConfigUtils.loadProperties(Collections.emptySet(), "META-INF/services/org.apache.dubbo.common.status.StatusChecker", false); Assertions.fail(); } catch (IllegalStateException expected) { assertThat(expected.getMessage(), containsString("only 1 META-INF/services/org.apache.dubbo.common.status.StatusChecker file is expected, but 2 dubbo.properties files found on class path:")); @@ -267,7 +251,7 @@ public void testLoadPropertiesMultiFileNotRootPathException() throws Exception { @Test public void testLoadPropertiesMultiFileNotRootPath() throws Exception { - Properties p = ConfigUtils.loadProperties("META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker", true); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker", true); Properties expected = new Properties(); expected.put("memory", "org.apache.dubbo.common.status.support.MemoryStatusChecker"); @@ -284,7 +268,7 @@ public void testGetPid() throws Exception { @Test public void testPropertiesWithStructedValue() throws Exception { - Properties p = ConfigUtils.loadProperties("parameters.properties", false); + Properties p = ConfigUtils.loadProperties(Collections.emptySet(), "parameters.properties", false); Properties expected = new Properties(); expected.put("dubbo.parameters", "[{a:b},{c_.d: r*}]"); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java index 5c71923ce62..97e8abbf3d6 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java @@ -31,7 +31,6 @@ import org.apache.dubbo.common.threadpool.manager.ExecutorRepository; import org.apache.dubbo.common.utils.ArrayUtils; import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.AbstractConfig; import org.apache.dubbo.config.ApplicationConfig; @@ -247,7 +246,6 @@ public static void reset() { */ @Deprecated public static void reset(boolean destroy) { - ConfigUtils.setProperties(null); DubboBootstrap.ignoreConfigState = true; if (destroy) { if (instance != null) { @@ -1061,8 +1059,8 @@ private void loadConfigs(Class cls) { try { // add default name config (same as id), e.g. dubbo.protocols.rest.port=1234 key = DUBBO + "." + AbstractConfig.getPluralTagName(cls) + "." + id + ".name"; - if (ConfigUtils.getProperties().getProperty(key) == null) { - ConfigUtils.getProperties().setProperty(key, id); + if (applicationModel.getApplicationEnvironment().getPropertiesConfiguration().getProperty(key) == null) { + applicationModel.getApplicationEnvironment().getPropertiesConfiguration().setProperty(key, id); addDefaultNameConfig = true; } @@ -1073,7 +1071,7 @@ private void loadConfigs(Class cls) { throw new IllegalStateException("load config failed, id: " + id + ", type:" + cls.getSimpleName()); } finally { if (addDefaultNameConfig && key != null) { - ConfigUtils.getProperties().remove(key); + applicationModel.getApplicationEnvironment().getPropertiesConfiguration().remove(key); } } } 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 b361957c2e1..298750ef6a8 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 @@ -19,6 +19,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URLBuilder; import org.apache.dubbo.common.config.ConfigurationUtils; +import org.apache.dubbo.common.config.PropertiesConfiguration; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.serialize.Serialization; @@ -63,6 +64,7 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ScopeModel; +import org.apache.dubbo.rpc.model.ScopeModelUtil; import org.apache.dubbo.rpc.support.MockInvoker; import java.net.InetAddress; @@ -464,11 +466,13 @@ public static void validateApplicationConfig(ApplicationConfig config) { } // backward compatibility - String wait = ConfigUtils.getProperty(SHUTDOWN_WAIT_KEY); + ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(config.getScopeModel()); + PropertiesConfiguration configuration = applicationModel.getApplicationEnvironment().getPropertiesConfiguration(); + String wait = configuration.getProperty(SHUTDOWN_WAIT_KEY); if (wait != null && wait.trim().length() > 0) { System.setProperty(SHUTDOWN_WAIT_KEY, wait.trim()); } else { - wait = ConfigUtils.getProperty(SHUTDOWN_WAIT_SECONDS_KEY); + wait = configuration.getProperty(SHUTDOWN_WAIT_SECONDS_KEY); if (wait != null && wait.trim().length() > 0) { System.setProperty(SHUTDOWN_WAIT_SECONDS_KEY, wait.trim()); } 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 32864f20d04..7f03914f5b9 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 @@ -16,7 +16,6 @@ */ package org.apache.dubbo.config; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.api.Greeting; import org.apache.dubbo.config.bootstrap.DubboBootstrap; @@ -390,7 +389,7 @@ public void testRefreshProperties() throws Exception { Properties properties = new Properties(); properties.load(this.getClass().getResourceAsStream("/dubbo.properties")); - ConfigUtils.setProperties(properties); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperties(properties); overrideConfig.refresh(); @@ -400,7 +399,6 @@ public void testRefreshProperties() throws Exception { //Assertions.assertEquals("properties", overrideConfig.getUseKeyAsProperty()); } finally { ApplicationModel.defaultModel().getApplicationEnvironment().destroy(); - ConfigUtils.setProperties(null); } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java index 427a265b229..92a7282af8b 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java @@ -18,7 +18,6 @@ package org.apache.dubbo.config; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -30,7 +29,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -164,11 +162,10 @@ public void testOverrideConfigBySystemProps() { @Test public void testOverrideConfigByDubboProps() { + ApplicationModel.defaultModel().getDefaultModule(); // Config instance has id, dubbo props has no id - Map props = new HashMap(); - props.put("dubbo.config-center.check", "false"); - props.put("dubbo.config-center.timeout", "1234"); - ConfigUtils.getProperties().putAll(props); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.check", "false"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-center.timeout", "1234"); try { // Config instance has id @@ -186,7 +183,7 @@ public void testOverrideConfigByDubboProps() { Assertions.assertEquals(3000L, configCenter.getTimeout()); Assertions.assertEquals(false, configCenter.isCheck()); } finally { - props.keySet().forEach(ConfigUtils.getProperties()::remove); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().refresh(); } } @@ -221,11 +218,10 @@ public void testOverrideConfigBySystemPropsWithId() { @Test public void testOverrideConfigByDubboPropsWithId() { + ApplicationModel.defaultModel().getDefaultModule(); // Config instance has id, dubbo props has id - Map props = new HashMap(); - props.put("dubbo.config-centers.configcenterA.check", "false"); - props.put("dubbo.config-centers.configcenterA.timeout", "1234"); - ConfigUtils.getProperties().putAll(props); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.check", "false"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.config-centers.configcenterA.timeout", "1234"); try { // Config instance has id @@ -244,7 +240,7 @@ public void testOverrideConfigByDubboPropsWithId() { Assertions.assertEquals(3000L, configCenter.getTimeout()); Assertions.assertEquals(false, configCenter.isCheck()); } finally { - props.keySet().forEach(ConfigUtils.getProperties()::remove); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().refresh(); } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java index 313fa71003e..2e06f0d2c6f 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java @@ -17,7 +17,6 @@ package org.apache.dubbo.config; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.config.api.DemoService; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -28,7 +27,6 @@ import org.junit.jupiter.api.Test; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; @@ -195,11 +193,10 @@ public void testOverrideConfigBySingularId() { @Test public void testOverrideConfigByDubboProps() { - Map props = new HashMap(); - props.put("dubbo.consumers.consumerA.check", "false"); - props.put("dubbo.consumers.consumerA.group", "demo"); - props.put("dubbo.consumers.consumerA.threads", "10"); - ConfigUtils.getProperties().putAll(props); + ApplicationModel.defaultModel().getDefaultModule(); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.check", "false"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.group", "demo"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().setProperty("dubbo.consumers.consumerA.threads", "10"); try { ConsumerConfig consumerConfig = new ConsumerConfig(); @@ -219,7 +216,7 @@ public void testOverrideConfigByDubboProps() { Assertions.assertEquals("groupA", consumerConfig.getGroup()); Assertions.assertEquals(10, consumerConfig.getThreads()); } finally { - props.keySet().forEach(ConfigUtils.getProperties()::remove); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().refresh(); } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index e29f75a1db6..34129dd7b94 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -826,8 +826,8 @@ public void testDifferentClassLoader() throws Exception { String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile(); basePath = java.net.URLDecoder.decode(basePath, "UTF-8"); - TestClassLoader classLoader1 = new TestClassLoader(basePath); - TestClassLoader classLoader2 = new TestClassLoader(basePath); + TestClassLoader classLoader1 = new TestClassLoader(Thread.currentThread().getContextClassLoader(), basePath); + TestClassLoader classLoader2 = new TestClassLoader(Thread.currentThread().getContextClassLoader(), basePath); Class class1 = classLoader1.loadClass(DemoService.class.getName(), false); Class class2 = classLoader2.loadClass(DemoService.class.getName(), false); @@ -962,7 +962,8 @@ private class InnerTest { private static class TestClassLoader extends ClassLoader { private String basePath; - public TestClassLoader(String basePath) { + public TestClassLoader(ClassLoader parent, String basePath) { + super(parent); this.basePath = basePath; } @@ -983,7 +984,7 @@ public Class loadClass(String name, boolean resolve) throws ClassNotFoundExce return loadedClass; } else { try { - if (name.startsWith("org.apache.dubbo.config")) { + if (name.equals("org.apache.dubbo.config.api.DemoService") || name.equals("org.apache.dubbo.config.api.DemoService$InnerClass")) { Class aClass = this.findClass(name); if (resolve) { this.resolveClass(aClass); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java index 7ee63af9431..0abaa22ba4b 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java @@ -19,7 +19,6 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.url.component.ServiceConfigURL; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.config.AbstractInterfaceConfig; import org.apache.dubbo.config.ApplicationConfig; @@ -123,21 +122,20 @@ public void checkApplication() { @Test public void compatibleApplicationShutdown() { try { - ConfigUtils.setProperties(null); System.clearProperty(SHUTDOWN_WAIT_KEY); System.clearProperty(SHUTDOWN_WAIT_SECONDS_KEY); writeDubboProperties(SHUTDOWN_WAIT_KEY, "100"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().refresh(); ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo")); Assertions.assertEquals("100", System.getProperty(SHUTDOWN_WAIT_KEY)); System.clearProperty(SHUTDOWN_WAIT_KEY); - ConfigUtils.setProperties(null); writeDubboProperties(SHUTDOWN_WAIT_SECONDS_KEY, "1000"); + ApplicationModel.defaultModel().getApplicationEnvironment().getPropertiesConfiguration().refresh(); ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo")); Assertions.assertEquals("1000", System.getProperty(SHUTDOWN_WAIT_SECONDS_KEY)); } finally { - ConfigUtils.setProperties(null); System.clearProperty("dubbo.application.name"); System.clearProperty(SHUTDOWN_WAIT_KEY); System.clearProperty(SHUTDOWN_WAIT_SECONDS_KEY); diff --git a/dubbo-container/dubbo-container-api/src/main/java/org/apache/dubbo/container/Main.java b/dubbo-container/dubbo-container-api/src/main/java/org/apache/dubbo/container/Main.java index c0f1c9bc1da..b43d3400ee6 100644 --- a/dubbo-container/dubbo-container-api/src/main/java/org/apache/dubbo/container/Main.java +++ b/dubbo-container/dubbo-container-api/src/main/java/org/apache/dubbo/container/Main.java @@ -20,7 +20,6 @@ import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.common.utils.ConfigUtils; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -54,7 +53,7 @@ public class Main { public static void main(String[] args) { try { if (ArrayUtils.isEmpty(args)) { - String config = ConfigUtils.getProperty(CONTAINER_KEY, LOADER.getDefaultExtensionName()); + String config = System.getProperty(CONTAINER_KEY, LOADER.getDefaultExtensionName()); args = COMMA_SPLIT_PATTERN.split(config); } diff --git a/dubbo-container/dubbo-container-spring/src/main/java/org/apache/dubbo/container/spring/SpringContainer.java b/dubbo-container/dubbo-container-spring/src/main/java/org/apache/dubbo/container/spring/SpringContainer.java index 390a57a5ddd..e3c0040328c 100644 --- a/dubbo-container/dubbo-container-spring/src/main/java/org/apache/dubbo/container/spring/SpringContainer.java +++ b/dubbo-container/dubbo-container-spring/src/main/java/org/apache/dubbo/container/spring/SpringContainer.java @@ -18,7 +18,6 @@ import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.container.Container; @@ -42,7 +41,7 @@ public static ClassPathXmlApplicationContext getContext() { @Override public void start() { - String configPath = ConfigUtils.getProperty(SPRING_CONFIG); + String configPath = System.getProperty(SPRING_CONFIG); if (StringUtils.isEmpty(configPath)) { configPath = DEFAULT_SPRING_CONFIG; } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java index 94e96f83c45..c48bbbcb11b 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java @@ -23,6 +23,8 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.metadata.MetadataInfo; import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ServiceModel; @@ -496,6 +498,16 @@ public ScopeModel getScopeModel() { return RpcContext.getServiceContext().getConsumerUrl().getScopeModel(); } + @Override + public FrameworkModel getOrDefaultFrameworkModel() { + return instance.getOrDefaultApplicationModel().getFrameworkModel(); + } + + @Override + public ApplicationModel getOrDefaultApplicationModel() { + return instance.getOrDefaultApplicationModel(); + } + @Override public ServiceModel getServiceModel() { return RpcContext.getServiceContext().getConsumerUrl().getServiceModel(); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/OverrideInstanceAddressURL.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/OverrideInstanceAddressURL.java index cc228d236c4..25e4e8c20ea 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/OverrideInstanceAddressURL.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/OverrideInstanceAddressURL.java @@ -21,10 +21,15 @@ import org.apache.dubbo.common.url.component.URLParam; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.metadata.MetadataInfo; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ScopeModel; +import org.apache.dubbo.rpc.model.ServiceModel; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class OverrideInstanceAddressURL extends InstanceAddressURL { @@ -264,6 +269,46 @@ public URLParam getOverrideParams() { return overrideParams; } + @Override + public String getRemoteApplication() { + return originUrl.getRemoteApplication(); + } + + @Override + public String getSide() { + return originUrl.getSide(); + } + + @Override + public ScopeModel getScopeModel() { + return originUrl.getScopeModel(); + } + + @Override + public FrameworkModel getOrDefaultFrameworkModel() { + return originUrl.getOrDefaultFrameworkModel(); + } + + @Override + public ApplicationModel getOrDefaultApplicationModel() { + return originUrl.getOrDefaultApplicationModel(); + } + + @Override + public ServiceModel getServiceModel() { + return originUrl.getServiceModel(); + } + + @Override + public Set getProviderFirstParams() { + return originUrl.getProviderFirstParams(); + } + + @Override + public void setProviderFirstParams(Set providerFirstParams) { + originUrl.setProviderFirstParams(providerFirstParams); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java index 3d5ff1b2028..d44c4287174 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java @@ -18,9 +18,9 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.Constants; @@ -118,9 +118,9 @@ protected void initChannel(SocketChannel ch) throws Exception { .addLast("client-idle-handler", new IdleStateHandler(heartbeatInterval, 0, 0, MILLISECONDS)) .addLast("handler", nettyClientHandler); - String socksProxyHost = ConfigUtils.getProperty(SOCKS_PROXY_HOST); + String socksProxyHost = ConfigurationUtils.getProperty(getUrl().getOrDefaultApplicationModel(), SOCKS_PROXY_HOST); if(socksProxyHost != null) { - int socksProxyPort = Integer.parseInt(ConfigUtils.getProperty(SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT)); + int socksProxyPort = Integer.parseInt(ConfigurationUtils.getProperty(getUrl().getOrDefaultApplicationModel(), SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT)); Socks5ProxyHandler socks5ProxyHandler = new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort)); ch.pipeline().addFirst(socks5ProxyHandler); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index 282e1bc1c0b..13ff94b6552 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -51,6 +51,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.remoting.Constants.DEFAULT_REMOTING_SERIALIZATION; import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY; import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY; @@ -269,7 +270,12 @@ private void waitForResultIfSync(AsyncRpcResult asyncResult, RpcInvocation invoc * must call {@link java.util.concurrent.CompletableFuture#get(long, TimeUnit)} because * {@link java.util.concurrent.CompletableFuture#get()} was proved to have serious performance drop. */ - asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS); + Object timeout = invocation.get(TIMEOUT_KEY); + if (timeout instanceof Integer) { + asyncResult.get((Integer) timeout, TimeUnit.MILLISECONDS); + } else { + asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS); + } } catch (InterruptedException e) { throw new RpcException("Interrupted unexpectedly while waiting for remote result to return! method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java index 2c4a8a1983a..bb449b1d86e 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java @@ -24,7 +24,6 @@ import org.apache.dubbo.common.serialize.support.SerializationOptimizer; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.Channel; @@ -435,7 +434,7 @@ private ExchangeClient[] getClients(URL url) { * The xml configuration should have a higher priority than properties. */ String shareConnectionsStr = url.getParameter(SHARE_CONNECTIONS_KEY, (String) null); - connections = Integer.parseInt(StringUtils.isBlank(shareConnectionsStr) ? ConfigUtils.getProperty(SHARE_CONNECTIONS_KEY, + connections = Integer.parseInt(StringUtils.isBlank(shareConnectionsStr) ? ConfigurationUtils.getProperty(url.getOrDefaultApplicationModel(), SHARE_CONNECTIONS_KEY, DEFAULT_SHARE_CONNECTIONS) : shareConnectionsStr); shareClients = getSharedClient(url, connections); }