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

crazyhzm 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 f9be618  Add onlyExtensionClassLoaderPackages support for 
ExtensionLoader (#9061)
f9be618 is described below

commit f9be6184b644e3127df6f13af0076d2618e0b982
Author: Albumen Kevin <[email protected]>
AuthorDate: Mon Oct 18 20:10:10 2021 +0800

    Add onlyExtensionClassLoaderPackages support for ExtensionLoader (#9061)
    
    * Add onlyExtensionClassLoaderPackages support for ExtensionLoader
    
    * revert temp
---
 .../dubbo/common/extension/ExtensionLoader.java    | 36 ++++++++++++++++------
 .../dubbo/common/extension/LoadingStrategy.java    | 12 ++++++++
 2 files changed, 38 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 3568cd6..d1dcaae 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
@@ -58,6 +58,7 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.TreeMap;
@@ -886,10 +887,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.overridden(), strategy.excludedPackages(), 
strategy.onlyExtensionClassLoaderPackages());
         String oldType = type.replace("org.apache", "com.alibaba");
         loadDirectory(extensionClasses, strategy.directory(), oldType, 
strategy.preferExtensionClassLoader(),
-            strategy.overridden(), strategy.excludedPackages());
+            strategy.overridden(), strategy.excludedPackages(), 
strategy.onlyExtensionClassLoaderPackages());
     }
 
     /**
@@ -915,11 +916,12 @@ public class ExtensionLoader<T> {
     }
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String 
dir, String type) {
-        loadDirectory(extensionClasses, dir, type, false, false);
+        loadDirectory(extensionClasses, dir, type, false, false, new 
String[]{}, new String[]{});
     }
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String 
dir, String type,
-                               boolean extensionLoaderClassLoaderFirst, 
boolean overridden, String... excludedPackages) {
+                               boolean extensionLoaderClassLoaderFirst, 
boolean overridden,
+                               String[] excludedPackages, String[] 
onlyExtensionClassLoaderPackages) {
         String fileName = dir + type;
         try {
             List<ClassLoader> classLoadersToLoad = new LinkedList<>();
@@ -939,7 +941,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);
+                        loadResource(extensionClasses, null, 
resources.nextElement(), overridden, excludedPackages, 
onlyExtensionClassLoaderPackages);
                     }
                 }
             } else {
@@ -948,7 +950,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);
+                loadFromClass(extensionClasses, overridden, urls, classLoader, 
excludedPackages, onlyExtensionClassLoaderPackages);
             }));
         } catch (Throwable t) {
             logger.error("Exception occurred when loading extension class 
(interface: " +
@@ -956,16 +958,17 @@ public class ExtensionLoader<T> {
         }
     }
 
-    private void loadFromClass(Map<String, Class<?>> extensionClasses, boolean 
overridden, Set<java.net.URL> urls, ClassLoader classLoader, String[] 
excludedPackages) {
+    private void loadFromClass(Map<String, Class<?>> extensionClasses, boolean 
overridden, Set<java.net.URL> urls, ClassLoader classLoader,
+                               String[] excludedPackages, String[] 
onlyExtensionClassLoaderPackages) {
         if (CollectionUtils.isNotEmpty(urls)) {
             for (java.net.URL url : urls) {
-                loadResource(extensionClasses, classLoader, url, overridden, 
excludedPackages);
+                loadResource(extensionClasses, classLoader, url, overridden, 
excludedPackages, onlyExtensionClassLoaderPackages);
             }
         }
     }
 
     private void loadResource(Map<String, Class<?>> extensionClasses, 
ClassLoader classLoader,
-                              java.net.URL resourceURL, boolean overridden, 
String... excludedPackages) {
+                              java.net.URL resourceURL, boolean overridden, 
String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) {
         try {
             try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
                 String line;
@@ -986,7 +989,8 @@ public class ExtensionLoader<T> {
                             } else {
                                 clazz = line;
                             }
-                            if (StringUtils.isNotEmpty(clazz) && 
!isExcluded(clazz, excludedPackages)) {
+                            if (StringUtils.isNotEmpty(clazz) && 
!isExcluded(clazz, excludedPackages)
+                                && !isExcludedByClassLoader(clazz, 
classLoader, onlyExtensionClassLoaderPackages)) {
                                 loadClass(extensionClasses, resourceURL, 
Class.forName(clazz, true, classLoader), name, overridden);
                             }
                         } catch (Throwable t) {
@@ -1014,6 +1018,18 @@ public class ExtensionLoader<T> {
         return false;
     }
 
+    private boolean isExcludedByClassLoader(String className, ClassLoader 
classLoader, String... onlyExtensionClassLoaderPackages) {
+        if (onlyExtensionClassLoaderPackages != null) {
+            for (String excludePackage : onlyExtensionClassLoaderPackages) {
+                if (className.startsWith(excludePackage + ".")) {
+                    // if target classLoader is not ExtensionLoader's 
classLoader should be excluded
+                    return 
!Objects.equals(ExtensionLoader.class.getClassLoader(), classLoader);
+                }
+            }
+        }
+        return false;
+    }
+
     private void loadClass(Map<String, Class<?>> extensionClasses, 
java.net.URL resourceURL, Class<?> clazz, String name,
                            boolean overridden) throws NoSuchMethodException {
         if (!type.isAssignableFrom(clazz)) {
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 2d4faf5..70c49c1 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,18 @@ public interface LoadingStrategy extends Prioritized {
     }
 
     /**
+     * To restrict some class that should loaded 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.
+     *
+     * @return class packages should loaded
+     * @since 3.0.4
+     */
+    default String[] onlyExtensionClassLoaderPackages() {
+        return new String[]{};
+    }
+
+    /**
      * Indicates current {@link LoadingStrategy} supports overriding other 
lower prioritized instances or not.
      *
      * @return if supports, return <code>true</code>, or <code>false</code>

Reply via email to