Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix spi classloader #1733

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class ClassLoaderManager {

private static FrameworkClassLoader frameworkClassLoader;

private static ClassLoader userClassLoader;

private ClassLoaderManager() {
}

Expand Down Expand Up @@ -88,6 +90,23 @@ public PluginClassLoader run() {
});
}

public static void setUserClassLoader(ClassLoader userClassLoader) {
ClassLoaderManager.userClassLoader = userClassLoader;
}

/**
* get ContextClassLoader or UserClassLoader
*
* @return ClassLoader
*/
public static ClassLoader getContextClassLoaderOrUserClassLoader() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
return classLoader;
}
return userClassLoader;
}

public static SermantClassLoader getSermantClassLoader() {
return sermantClassLoader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public ClassLoaderLoadClassInterceptor() {

@Override
public ExecuteContext before(ExecuteContext context) throws Exception {
ClassLoaderManager.setUserClassLoader((ClassLoader) context.getObject());
return context;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.sermant.core.plugin.classloader;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.config.ConfigManager;
import io.sermant.core.plugin.agent.config.AgentConfig;
Expand Down Expand Up @@ -133,9 +134,16 @@ public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundExce

private Class<?> getClassFromLocalClassLoader(String name) {
ClassLoader loader = localLoader.get(Thread.currentThread().getId());

if (loader == null) {
LOGGER.log(Level.FINE, "localLoader is null, thread name is {0}, classs name is {1}.",
new Object[]{Thread.currentThread().getName(), name});
}
if (loader == null && useContextLoader) {
loader = Thread.currentThread().getContextClassLoader();
loader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
if (loader == null) {
LOGGER.log(Level.WARNING, "contextClassLoader is null, thread name is {0}, classs name is {1}.",
new Object[]{Thread.currentThread().getName(), name});
}
}
Class<?> clazz = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.core.plugin.subscribe.processor;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.service.dynamicconfig.common.DynamicConfigEvent;
import io.sermant.core.service.dynamicconfig.common.DynamicConfigListener;

Expand All @@ -43,7 +44,7 @@ public class IntegratedEventListenerAdapter implements DynamicConfigListener {
public IntegratedEventListenerAdapter(ConfigProcessor processor, String rawGroup) {
this.processor = processor;
this.rawGroup = rawGroup;
this.classLoader = Thread.currentThread().getContextClassLoader();
this.classLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
}

@Override
Expand All @@ -54,7 +55,7 @@ public void process(DynamicConfigEvent event) {

// The classloader at subscription time may not be the same as the classloader at listener configuration
// time, so need to restore it
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader currentClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
processor.process(rawGroup, event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.core.utils;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;

import java.io.IOException;
Expand Down Expand Up @@ -111,7 +112,7 @@ public static Optional<Class<?>> loadClass(String className, ClassLoader classLo
public static Optional<Object> createInstance(String className, ClassLoader classLoader, Class<?>[] paramTypes) {
ClassLoader curClassLoader = classLoader;
if (curClassLoader == null) {
curClassLoader = Thread.currentThread().getContextClassLoader();
curClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
}
try {
final Class<?> clazz = curClassLoader.loadClass(className);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.core.utils;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;

import java.lang.reflect.AccessibleObject;
Expand Down Expand Up @@ -166,7 +167,7 @@ private static Optional<Class<?>> loadClass(String className) {
return Optional.empty();
}
return CLASS_CACHE.computeIfAbsent(className, value -> {
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
try {
return Optional.ofNullable(contextClassLoader.loadClass(className));
} catch (ClassNotFoundException ignored) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.sermant.implement.config;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.exception.SermantRuntimeException;

import org.yaml.snakeyaml.LoaderOptions;
Expand All @@ -35,7 +36,7 @@ public class SermantYamlConstructor extends Constructor {
*/
public SermantYamlConstructor() {
super(Object.class, new LoaderOptions());
loader = Thread.currentThread().getContextClassLoader();
loader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.auth.impl.NacosAuthLoginConstant;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.config.ConfigManager;
import io.sermant.core.service.dynamicconfig.config.DynamicConfig;
Expand Down Expand Up @@ -229,7 +230,7 @@ private Properties createProperties(String connectString, int sessionTimeout, St
* @throws NacosInitException Connect to Nacos failed
*/
private void createNacosClient(String connectString, Properties properties) {
ClassLoader tempClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader tempClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
try {
nacosClient = new NacosClient(properties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.dynamic.config.inject;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.plugin.config.PluginConfigManager;
import io.sermant.core.service.inject.ClassInjectDefine;
import io.sermant.core.utils.ClassUtils;
Expand All @@ -42,6 +43,7 @@ public Plugin plugin() {
@Override
public boolean canInject() {
return PluginConfigManager.getPluginConfig(DynamicConfiguration.class).isEnableDynamicConfig()
&& ClassUtils.loadClass(REFRESH_CLASS, Thread.currentThread().getContextClassLoader()).isPresent();
&& ClassUtils.loadClass(REFRESH_CLASS, ClassLoaderManager.getContextClassLoaderOrUserClassLoader())
.isPresent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.dynamic.config.interceptors;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.service.ServiceManager;
Expand Down Expand Up @@ -94,7 +95,7 @@ private boolean isHasMethodLoadSpringFactories() {

private void injectConfigurationsWithLowVersion(Object result, String factoryName) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
if (result instanceof List) {
final List<String> convertedResult = (List<String>) result;
CLASS_DEFINES.forEach(classInjectDefine -> {
Expand All @@ -108,7 +109,7 @@ private void injectConfigurationsWithLowVersion(Object result, String factoryNam

private void injectConfigurations(Object result) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
final boolean isMultiValueMap = result instanceof MultiValueMap;
if (result instanceof Map) {
// spring 高版本处理, 针对List其为不可变list,需做一层处理
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.flowcontrol.common.handler.retry;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.config.PluginConfigManager;
import io.sermant.core.service.xds.entity.XdsRetryPolicy;
Expand Down Expand Up @@ -59,7 +60,8 @@ protected final Class<? extends Throwable>[] findClass(String[] classNames) {
final List<Class<?>> result = new ArrayList<>(classNames.length);
for (String className : classNames) {
try {
result.add(Class.forName(className, false, Thread.currentThread().getContextClassLoader()));
result.add(Class.forName(className, false,
ClassLoaderManager.getContextClassLoaderOrUserClassLoader()));
} catch (ClassNotFoundException exception) {
LoggerFactory.getLogger().info(String.format(Locale.ENGLISH,
"Can not find retry exception class %s", className));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.flowcontrol.config;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.plugin.agent.interceptor.AbstractInterceptor;
Expand Down Expand Up @@ -101,7 +102,7 @@ private boolean isHasMethodLoadSpringFactories() {

private void injectConfigurationsWithLowVersion(Object result, String factoryName) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
if (result instanceof List) {
final List<String> convertedResult = (List<String>) result;
CLASS_DEFINES.forEach(classInjectDefine -> {
Expand All @@ -115,7 +116,7 @@ private void injectConfigurationsWithLowVersion(Object result, String factoryNam

private void injectConfigurations(Object result) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
final boolean isMultiValueMap = result instanceof MultiValueMap;
if (result instanceof Map) {
// Spring high version processing, for List, which is an immutable list, a layer of processing is required.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.flowcontrol.inject;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.service.inject.ClassInjectDefine;
import io.sermant.core.utils.ClassUtils;

Expand Down Expand Up @@ -53,6 +54,8 @@ public Plugin plugin() {
}

private boolean isLoadedClass(String className) {
return ClassUtils.loadClass(className, Thread.currentThread().getContextClassLoader(), true).isPresent();
return ClassUtils
.loadClass(className, ClassLoaderManager.getContextClassLoaderOrUserClassLoader(), true)
.isPresent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.flowcontrol.retry;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.utils.ClassUtils;
import io.sermant.flowcontrol.retry.cluster.AlibabaDubboCluster;
Expand Down Expand Up @@ -70,7 +71,7 @@ protected ExecuteContext doAfter(ExecuteContext context) {
return context;
}
final Optional<Class<?>> retryInvokerClass;
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
if (APACHE_DUBBO_CLUSTER_CLASS_NAME.equals(type.getName())) {
ClassUtils.defineClass(
"io.sermant.flowcontrol.retry.cluster.ApacheDubboClusterInvoker", contextClassLoader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.loadbalancer.interceptor;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.plugin.agent.interceptor.AbstractInterceptor;
Expand Down Expand Up @@ -117,7 +118,7 @@ private void fillSupportRules(String extensionLoaderClazz, String lbClassName) {
}
supportRules = new HashSet<>();
final Optional<Class<?>> lbClazz = ClassUtils
.loadClass(lbClassName, Thread.currentThread().getContextClassLoader(), true);
.loadClass(lbClassName, ClassLoaderManager.getContextClassLoaderOrUserClassLoader(), true);
if (!lbClazz.isPresent()) {
return;
}
Expand All @@ -141,7 +142,7 @@ private void fillSupportRules(String extensionLoaderClazz, String lbClassName) {
}

private boolean isAlibaba() {
return ClassUtils.loadClass(ALIBABA_LOADER, Thread.currentThread().getContextClassLoader(), false)
return ClassUtils.loadClass(ALIBABA_LOADER, ClassLoaderManager.getContextClassLoaderOrUserClassLoader(), false)
.isPresent();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.sermant.loadbalancer.interceptor;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.plugin.agent.interceptor.AbstractInterceptor;
Expand Down Expand Up @@ -101,7 +102,7 @@ private boolean isHasMethodLoadSpringFactories() {

private void injectConfigurationsWithLowVersion(Object result, String factoryName) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
if (result instanceof List) {
final List<String> convertedResult = (List<String>) result;
CLASS_DEFINES.forEach(classInjectDefine -> {
Expand All @@ -115,7 +116,7 @@ private void injectConfigurationsWithLowVersion(Object result, String factoryNam

private void injectConfigurations(Object result) {
final ClassInjectService service = ServiceManager.getService(ClassInjectService.class);
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
final boolean isMultiValueMap = result instanceof MultiValueMap;
if (result instanceof Map) {
// Spring high version processing, for List, which is an immutable list, a layer of processing is required.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.IRule;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.plugin.agent.entity.ExecuteContext;
import io.sermant.core.plugin.agent.interceptor.AbstractInterceptor;
Expand Down Expand Up @@ -67,7 +68,7 @@ public class RibbonLoadBalancerInterceptor extends AbstractInterceptor {

private final Function<RibbonLoadbalancerType, Optional<AbstractLoadBalancerRule>> ruleCreator = type -> {
final String clazzName = type.getClazzName();
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
try {
final Class<?> ruleClazz = contextClassLoader.loadClass(clazzName);
return Optional.of((AbstractLoadBalancerRule) ruleClazz.newInstance());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.sermant.dubbo.registry.utils;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.utils.ClassLoaderUtils;
import io.sermant.dubbo.registry.cache.DubboCache;
Expand Down Expand Up @@ -100,7 +101,7 @@ private ReflectUtils() {
* @return Host class
*/
public static Optional<Class<?>> defineClass(String className) {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader contextClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
try {
return Optional.of(ClassLoaderUtils.defineClass(className, contextClassLoader,
ClassLoaderUtils.getClassResource(ReflectUtils.class.getClassLoader(), className)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;

import io.sermant.core.classloader.ClassLoaderManager;
import io.sermant.core.common.LoggerFactory;
import io.sermant.core.utils.StringUtils;
import io.sermant.registry.config.NacosRegisterConfig;
Expand Down Expand Up @@ -57,7 +58,7 @@ private NamingServiceUtils() {
public static NamingService buildNamingService(Map<String, String> parameters, NacosRegisterConfig registerConfig,
RegisterServiceCommonConfig commonConfig) {
Properties nacosProperties = buildNacosProperties(parameters, registerConfig, commonConfig);
ClassLoader tempClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader tempClassLoader = ClassLoaderManager.getContextClassLoaderOrUserClassLoader();
Thread.currentThread().setContextClassLoader(NamingServiceUtils.class.getClassLoader());
try {
return NacosFactory.createNamingService(nacosProperties);
Expand Down
Loading
Loading