You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2022/02/18 02:56:58 UTC

[dubbo] branch 3.0 updated: [3.0] Add Included package filter in ExtensionLoader (#9697)

This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 8059985  [3.0] Add Included package filter in ExtensionLoader (#9697)
8059985 is described below

commit 80599857a8e28a0b3973afeb7167e0cd8485f354
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Fri Feb 18 10:56:01 2022 +0800

    [3.0] Add Included package filter in ExtensionLoader (#9697)
    
    * [3.0] Add Included package filter in ExtensionLoader
    
    * rename
    
    * rename
---
 .../dubbo/common/extension/ExtensionLoader.java    | 35 +++++++++++++++-------
 .../dubbo/common/extension/LoadingStrategy.java    | 25 ++++++++++++++++
 2 files changed, 50 insertions(+), 10 deletions(-)

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 1353864..6fc4d69 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
@@ -941,10 +941,10 @@ public class ExtensionLoader<T> {
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, LoadingStrategy strategy, String type) {
         loadDirectory(extensionClasses, strategy.directory(), type, strategy.preferExtensionClassLoader(),
-            strategy.overridden(), strategy.excludedPackages(), strategy.onlyExtensionClassLoaderPackages());
+            strategy.overridden(), strategy.includedPackages(), strategy.excludedPackages(), strategy.onlyExtensionClassLoaderPackages());
         String oldType = type.replace("org.apache", "com.alibaba");
         loadDirectory(extensionClasses, strategy.directory(), oldType, strategy.preferExtensionClassLoader(),
-            strategy.overridden(), strategy.excludedPackages(), strategy.onlyExtensionClassLoaderPackages());
+            strategy.overridden(), strategy.includedPackagesInCompatibleType(), strategy.excludedPackages(), strategy.onlyExtensionClassLoaderPackages());
     }
 
     /**
@@ -970,11 +970,11 @@ public class ExtensionLoader<T> {
     }
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type) {
-        loadDirectory(extensionClasses, dir, type, false, false, new String[]{}, new String[]{});
+        loadDirectory(extensionClasses, dir, type, false, false, new String[]{}, new String[]{}, new String[]{});
     }
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
-                               boolean extensionLoaderClassLoaderFirst, boolean overridden,
+                               boolean extensionLoaderClassLoaderFirst, boolean overridden, String[] includedPackages,
                                String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
         String fileName = dir + type;
         try {
@@ -995,7 +995,7 @@ public class ExtensionLoader<T> {
                 Enumeration<java.net.URL> resources = ClassLoader.getSystemResources(fileName);
                 if (resources != null) {
                     while (resources.hasMoreElements()) {
-                        loadResource(extensionClasses, null, resources.nextElement(), overridden, excludedPackages, onlyExtensionClassLoaderPackages);
+                        loadResource(extensionClasses, null, resources.nextElement(), overridden, includedPackages, excludedPackages, onlyExtensionClassLoaderPackages);
                     }
                 }
             } else {
@@ -1004,7 +1004,7 @@ public class ExtensionLoader<T> {
 
             Map<ClassLoader, Set<java.net.URL>> resources = ClassLoaderResourceLoader.loadResources(fileName, classLoadersToLoad);
             resources.forEach(((classLoader, urls) -> {
-                loadFromClass(extensionClasses, overridden, urls, classLoader, excludedPackages, onlyExtensionClassLoaderPackages);
+                loadFromClass(extensionClasses, overridden, urls, classLoader, includedPackages, excludedPackages, onlyExtensionClassLoaderPackages);
             }));
         } catch (Throwable t) {
             logger.error("Exception occurred when loading extension class (interface: " +
@@ -1013,16 +1013,16 @@ public class ExtensionLoader<T> {
     }
 
     private void loadFromClass(Map<String, Class<?>> extensionClasses, boolean overridden, Set<java.net.URL> urls, ClassLoader classLoader,
-                               String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
+                               String[] includedPackages, String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
         if (CollectionUtils.isNotEmpty(urls)) {
             for (java.net.URL url : urls) {
-                loadResource(extensionClasses, classLoader, url, overridden, excludedPackages, onlyExtensionClassLoaderPackages);
+                loadResource(extensionClasses, classLoader, url, overridden, includedPackages, excludedPackages, onlyExtensionClassLoaderPackages);
             }
         }
     }
 
     private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
-                              java.net.URL resourceURL, boolean overridden, String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
+                              java.net.URL resourceURL, boolean overridden, String[] includedPackages, String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
         try {
             try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
                 String line;
@@ -1043,7 +1043,7 @@ public class ExtensionLoader<T> {
                             } else {
                                 clazz = line;
                             }
-                            if (StringUtils.isNotEmpty(clazz) && !isExcluded(clazz, excludedPackages)
+                            if (StringUtils.isNotEmpty(clazz) && !isExcluded(clazz, excludedPackages) && isIncluded(clazz, includedPackages)
                                 && !isExcludedByClassLoader(clazz, classLoader, onlyExtensionClassLoaderPackages)) {
                                 loadClass(extensionClasses, resourceURL, Class.forName(clazz, true, classLoader), name, overridden);
                             }
@@ -1061,6 +1061,21 @@ public class ExtensionLoader<T> {
         }
     }
 
+    private boolean isIncluded(String className, String... includedPackages) {
+        if (includedPackages != null && includedPackages.length > 0) {
+            for (String includedPackage : includedPackages) {
+                if (className.startsWith(includedPackage + ".")) {
+                    // one match, return true
+                    return true;
+                }
+            }
+            // none matcher match, return false
+            return false;
+        }
+        // matcher is empty, return true
+        return true;
+    }
+
     private boolean isExcluded(String className, String... excludedPackages) {
         if (excludedPackages != null) {
             for (String excludePackage : excludedPackages) {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java
index b41f132..c60300a 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java
@@ -31,6 +31,31 @@ public interface LoadingStrategy extends Prioritized {
     }
 
     /**
+     * To restrict some class that should not be loaded from `org.apache.dubbo` package type SPI class.
+     * For example, we can restrict the implementation class which package is `org.xxx.xxx`
+     * can be loaded as SPI implementation.
+     *
+     * @return packages can be loaded in `org.apache.dubbo`'s SPI
+     */
+    default String[] includedPackages() {
+        // default match all
+        return null;
+    }
+
+    /**
+     * To restrict some class that should not be loaded from `org.alibaba.dubbo`(for compatible purpose)
+     * package type SPI class.
+     * For example, we can restrict the implementation class which package is `org.xxx.xxx`
+     * can be loaded as SPI implementation
+     *
+     * @return packages can be loaded in `org.alibaba.dubbo`'s SPI
+     */
+    default String[] includedPackagesInCompatibleType() {
+        // default match all
+        return null;
+    }
+
+    /**
      * To restrict some class that should load from Dubbo's ClassLoader.
      * For example, we can restrict the class declaration in `org.apache.dubbo` package should
      * be loaded from Dubbo's ClassLoader and users cannot declare these classes.