You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by cr...@apache.org on 2021/10/18 12:10:29 UTC
[dubbo] branch 3.0 updated: Add onlyExtensionClassLoaderPackages
support for ExtensionLoader (#9061)
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 <jh...@gmail.com>
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>