From baf706a88b79f24002593bdba8a3790d75f540c9 Mon Sep 17 00:00:00 2001 From: luanwenfei Date: Wed, 1 Nov 2023 11:44:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=AF=E4=BB=A5=E4=BB=8E?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E7=B1=BB=E5=8A=A0=E8=BD=BD=E5=99=A8=E4=B8=AD?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=88=B0=E5=AE=BF=E4=B8=BB=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/classloader/PluginClassLoader.java | 83 +++++++++++++------ .../classloader/ServiceClassLoader.java | 4 +- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/PluginClassLoader.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/PluginClassLoader.java index 9b0ac6177e..37350c2ff1 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/PluginClassLoader.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/PluginClassLoader.java @@ -22,6 +22,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; +import java.util.Map; /** * 加载插件主模块的类加载器 @@ -37,6 +38,11 @@ public class PluginClassLoader extends URLClassLoader { */ private final boolean useContextLoader; + /** + * 对ClassLoader内部已加载的Class的管理 + */ + private final Map> pluginClassMap = new HashMap<>(); + /** * 构造方法 * @@ -48,6 +54,23 @@ public PluginClassLoader(URL[] urls, ClassLoader parent) { useContextLoader = ConfigManager.getConfig(AgentConfig.class).isUseContextLoader(); } + /** + * 加载插件服务包中的类并维护 + * + * @param name 全限定名 + * @return Class对象 + */ + private Class loadPluginClass(String name) { + if (!pluginClassMap.containsKey(name)) { + try { + pluginClassMap.put(name, findClass(name)); + } catch (ClassNotFoundException ignored) { + pluginClassMap.put(name, null); + } + } + return pluginClassMap.get(name); + } + /** * 向类加载器中添加类的搜索路径 * @@ -64,42 +87,48 @@ public Class loadClass(String name) throws ClassNotFoundException { @Override public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - Class clazz = null; + synchronized (getClassLoadingLock(name)) { + Class clazz = loadPluginClass(name); - try { - clazz = super.loadClass(name, resolve); - } catch (ClassNotFoundException ignored) { - // ignored - } + // 自身无法加载类,则通过Sermant搜索路径中加载 + if (clazz == null) { + try { + clazz = super.loadClass(name, resolve); + } catch (ClassNotFoundException ignored) { + // 捕获类找不到的异常,下一步会进入localLoader中去加载类 + // ignored + } + } - // 无法从Sermant搜索路径中找到类,则尝试通过线程绑定的局部类加载器加载 - if (clazz == null) { - ClassLoader loader = localLoader.get(Thread.currentThread().getId()); + // 无法从Sermant搜索路径中找到类,则尝试通过线程绑定的局部类加载器加载 + if (clazz == null) { + ClassLoader loader = localLoader.get(Thread.currentThread().getId()); - if (loader == null && useContextLoader) { - loader = Thread.currentThread().getContextClassLoader(); - } + if (loader == null && useContextLoader) { + loader = Thread.currentThread().getContextClassLoader(); + } - // 确保局部类加载器不是当前类加载器,否则会stackoverflow - if (loader != null && !this.equals(loader)) { - try { - clazz = loader.loadClass(name); - } catch (ClassNotFoundException e) { - // 无法找到类,忽略,后续抛出异常 + // 确保局部类加载器不是当前类加载器,否则会stackoverflow + if (loader != null && !this.equals(loader)) { + try { + clazz = loader.loadClass(name); + } catch (ClassNotFoundException e) { + // 无法找到类,忽略,后续抛出异常 + } } } - } - // 如果无法找到类,则抛出异常 - if (clazz == null) { - throw new ClassNotFoundException("Sermant pluginClassLoader can not load class: " + name); - } + // 如果无法找到类,则抛出异常 + if (clazz == null) { + throw new ClassNotFoundException("Sermant pluginClassLoader can not load class: " + name); + } - // 如果有需要则解析该类 - if (resolve) { - resolveClass(clazz); + // 如果有需要则解析该类 + if (resolve) { + resolveClass(clazz); + } + return clazz; } - return clazz; } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/ServiceClassLoader.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/ServiceClassLoader.java index 32d409639d..a6326fda7f 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/ServiceClassLoader.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/classloader/ServiceClassLoader.java @@ -55,7 +55,7 @@ public ServiceClassLoader(URL[] urls, ClassLoader parent) { * @param name 全限定名 * @return Class对象 */ - private Class loadPluginClass(String name) { + private Class loadServiceClass(String name) { if (!serviceClassMap.containsKey(name)) { try { serviceClassMap.put(name, findClass(name)); @@ -74,7 +74,7 @@ public Class loadClass(String name) throws ClassNotFoundException { @Override public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { - Class clazz = loadPluginClass(name); + Class clazz = loadServiceClass(name); if (clazz == null) { clazz = super.loadClass(name, resolve);