[
https://issues.apache.org/jira/browse/SCB-715?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16533404#comment-16533404
]
ASF GitHub Bot commented on SCB-715:
------------------------------------
liubao68 closed pull request #790: [SCB-715]working in thread that do not have
context class loader
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/790
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
index 66bb661e1..2d3ed01ef 100644
---
a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
+++
b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
@@ -24,6 +24,7 @@
import java.util.Arrays;
import java.util.List;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -90,9 +91,7 @@ private JavassistUtils() {
throw new Error("values is not allowed empty.");
}
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
+ classLoader = JvmUtils.correctClassLoader(classLoader);
ClassPool classPool = getOrCreateClassPool(classLoader);
CtClass ctClass = classPool.makeClass(clsName);
@@ -140,9 +139,7 @@ private static void addEnumValuesMethod(CtClass ctClass,
List<String> values) th
}
public static CtClass createCtClass(ClassLoader classLoader, ClassConfig
config) {
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
+ classLoader = JvmUtils.correctClassLoader(classLoader);
ClassPool classPool = getOrCreateClassPool(classLoader);
CtClass ctClass = classPool.getOrNull(config.getClassName());
@@ -195,18 +192,14 @@ public static CtClass createCtClass(ClassLoader
classLoader, ClassConfig config)
}
public static Class<?> createClass(ClassLoader classLoader, ClassConfig
config) {
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
+ classLoader = JvmUtils.correctClassLoader(classLoader);
CtClass ctClass = createCtClass(classLoader, config);
return createClass(classLoader, ctClass);
}
public static Class<?> createClass(ClassLoader classLoader, CtClass ctClass)
{
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
+ classLoader = JvmUtils.correctClassLoader(classLoader);
String clsName = ctClass.getName();
try {
diff --git
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
index a23f98cdd..ca8f9bad6 100644
---
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
+++
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
@@ -20,6 +20,7 @@
import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
@@ -40,7 +41,7 @@
private static final Object LOCK = new Object();
private static ScopedProtobufSchemaManager
defaultScopedProtobufSchemaManager = new ScopedProtobufSchemaManager(
- Thread.currentThread().getContextClassLoader());
+ JvmUtils.findClassLoader());
static {
// 支持在idl中定义empty message
diff --git
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
index d2b85f2b8..002c009c9 100644
---
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
+++
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
@@ -26,6 +26,7 @@
import org.apache.servicecomb.common.javassist.JavassistUtils;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -39,10 +40,7 @@
private Map<String, WrapSchema> schemaCache = new ConcurrentHashMapEx<>();
public ScopedProtobufSchemaManager(ClassLoader classLoader) {
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
- this.classLoader = classLoader;
+ this.classLoader = JvmUtils.correctClassLoader(classLoader);
}
// 为了支持method args的场景,全部实现ProtobufMessageWrapper接口,有的场景有点浪费,不过无关紧要
diff --git
a/core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceMeta.java
b/core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceMeta.java
index e7a012a50..7101094b9 100644
---
a/core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceMeta.java
+++
b/core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceMeta.java
@@ -24,6 +24,7 @@
import java.util.concurrent.ConcurrentHashMap;
import org.apache.servicecomb.foundation.common.RegisterManager;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.apache.servicecomb.serviceregistry.RegistryUtils;
import org.apache.servicecomb.serviceregistry.api.Const;
@@ -53,7 +54,7 @@
private Map<String, Object> extData = new ConcurrentHashMap<>();
public MicroserviceMeta(String microserviceName) {
- classLoader = Thread.currentThread().getContextClassLoader();
+ classLoader = JvmUtils.findClassLoader();
parseMicroserviceName(microserviceName);
createOperationMgr("Operation meta mgr for microservice " +
microserviceName);
idSchemaMetaMgr = new RegisterManager<>("Schema meta id mgr for
microservice " + microserviceName);
diff --git
a/core/src/main/java/org/apache/servicecomb/core/definition/classloader/DefaultMicroserviceClassLoaderFactory.java
b/core/src/main/java/org/apache/servicecomb/core/definition/classloader/DefaultMicroserviceClassLoaderFactory.java
index 1534da3a7..6e0222ded 100644
---
a/core/src/main/java/org/apache/servicecomb/core/definition/classloader/DefaultMicroserviceClassLoaderFactory.java
+++
b/core/src/main/java/org/apache/servicecomb/core/definition/classloader/DefaultMicroserviceClassLoaderFactory.java
@@ -17,11 +17,13 @@
package org.apache.servicecomb.core.definition.classloader;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
+
public class DefaultMicroserviceClassLoaderFactory implements
MicroserviceClassLoaderFactory {
public static final MicroserviceClassLoaderFactory INSTANCE = new
DefaultMicroserviceClassLoaderFactory();
@Override
public ClassLoader create(String appId, String microserviceName, String
version) {
- return Thread.currentThread().getContextClassLoader();
+ return JvmUtils.findClassLoader();
}
}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/definition/classloader/MicroserviceClassLoader.java
b/core/src/main/java/org/apache/servicecomb/core/definition/classloader/MicroserviceClassLoader.java
index cac83e837..2473aaa8c 100644
---
a/core/src/main/java/org/apache/servicecomb/core/definition/classloader/MicroserviceClassLoader.java
+++
b/core/src/main/java/org/apache/servicecomb/core/definition/classloader/MicroserviceClassLoader.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.core.definition.classloader;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,7 +32,7 @@
public MicroserviceClassLoader(String appId, String microserviceName, String
version) {
- super(Thread.currentThread().getContextClassLoader());
+ super(JvmUtils.findClassLoader());
this.appId = appId;
this.microserviceName = microserviceName;
diff --git
a/core/src/main/java/org/apache/servicecomb/core/definition/schema/AbstractSchemaFactory.java
b/core/src/main/java/org/apache/servicecomb/core/definition/schema/AbstractSchemaFactory.java
index 30e0dfffd..9d62c52b7 100644
---
a/core/src/main/java/org/apache/servicecomb/core/definition/schema/AbstractSchemaFactory.java
+++
b/core/src/main/java/org/apache/servicecomb/core/definition/schema/AbstractSchemaFactory.java
@@ -26,6 +26,7 @@
import org.apache.servicecomb.core.definition.SchemaMeta;
import org.apache.servicecomb.core.definition.SchemaUtils;
import org.apache.servicecomb.core.definition.loader.SchemaLoader;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.apache.servicecomb.serviceregistry.api.Const;
import
org.apache.servicecomb.swagger.generator.core.CompositeSwaggerGeneratorContext;
import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
@@ -76,7 +77,7 @@ protected Swagger loadSwagger(CONTEXT context) {
protected Swagger loadSwagger(String microserviceName, String schemaId) {
String path = generateSchemaPath(microserviceName, schemaId);
- URL url = Thread.currentThread().getContextClassLoader().getResource(path);
+ URL url = JvmUtils.findClassLoader().getResource(path);
if (url == null) {
return null;
}
diff --git
a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
index 52f1c9bdf..3b55ebb17 100644
---
a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
+++
b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
@@ -21,6 +21,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Set;
+import java.util.stream.IntStream;
import javax.inject.Inject;
@@ -83,7 +84,20 @@ public static void main(String[] args) throws Exception {
TestMgr.summary();
}
+ private static void testContextClassLoaderIsNull() {
+ IntStream.range(0, 100).parallel().forEach(item -> {
+ if (Thread.currentThread().getName().equals("main")) {
+ return;
+ }
+ // in web environment, this could be null, here we just mock a null
class loader.
+ Thread.currentThread().setContextClassLoader(null);
+ TestMgr.check(null, test.postTestStatic(2));
+ });
+ }
+
public static void run() throws Exception {
+ testContextClassLoaderIsNull();
+
smartcare = BeanUtils.getBean("smartcare");
String microserviceName = "pojo";
diff --git
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
index e2b2b8617..48a9baab4 100644
---
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
+++
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
@@ -50,4 +50,22 @@ private JvmUtils() {
return null;
}
}
+
+ /**
+ * find a property class loader to avoid null
+ */
+ public static ClassLoader correctClassLoader(ClassLoader classLoader) {
+ ClassLoader targetClassLoader = classLoader;
+ if (targetClassLoader == null) {
+ targetClassLoader = Thread.currentThread().getContextClassLoader();
+ }
+ if (targetClassLoader == null) {
+ targetClassLoader = JvmUtils.class.getClassLoader();
+ }
+ return targetClassLoader;
+ }
+
+ public static ClassLoader findClassLoader() {
+ return correctClassLoader(null);
+ }
}
\ No newline at end of file
diff --git
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigMapping.java
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigMapping.java
index f29e9afb7..2c381bb21 100644
---
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigMapping.java
+++
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigMapping.java
@@ -28,6 +28,7 @@
import java.util.Map;
import org.apache.commons.configuration.Configuration;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +41,7 @@
private static final Logger LOGGER =
LoggerFactory.getLogger(ConfigMapping.class);
static {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ ClassLoader loader = JvmUtils.findClassLoader();
List<URL> urlList = new ArrayList<>();
configMap = new HashMap<String, Object>();
Enumeration<URL> urls;
diff --git
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/archaius/sources/AbstractConfigLoader.java
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/archaius/sources/AbstractConfigLoader.java
index acdde740f..fad59592a 100644
---
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/archaius/sources/AbstractConfigLoader.java
+++
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/archaius/sources/AbstractConfigLoader.java
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
@@ -88,7 +89,7 @@ public ConfigModel load(URL url) throws IOException {
protected List<URL> findURLFromClassPath(String resourceName) throws
IOException {
List<URL> urlList = new ArrayList<>();
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ ClassLoader loader = JvmUtils.findClassLoader();
Enumeration<URL> urls = loader.getResources(resourceName);
while (urls.hasMoreElements()) {
urlList.add(urls.nextElement());
diff --git
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 06ffb9bc1..b8213651b 100644
---
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -33,6 +33,7 @@
import org.apache.servicecomb.core.provider.consumer.SyncResponseExecutor;
import org.apache.servicecomb.foundation.common.cache.VersionedCache;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.apache.servicecomb.loadbalance.filter.CseServerDiscoveryFilter;
import org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter;
import org.apache.servicecomb.loadbalance.filter.TransactionControlFilter;
@@ -365,7 +366,7 @@ private void loadFilter(String filter, LoadBalancer lb) {
String.format(Configuration.SERVER_LIST_FILTER_CLASS_HOLDER, filter));
if (!StringUtils.isEmpty(className)) {
try {
- Class<?> filterClass = Class.forName(className, true,
Thread.currentThread().getContextClassLoader());
+ Class<?> filterClass = Class.forName(className, true,
JvmUtils.findClassLoader());
if (ServerListFilterExt.class.isAssignableFrom(filterClass)) {
ServerListFilterExt ext = (ServerListFilterExt)
filterClass.newInstance();
ext.setName(filter);
diff --git
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
index cc3197e06..b6df5ef21 100644
---
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
+++
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
@@ -19,6 +19,7 @@
import java.util.Collection;
import org.apache.commons.lang.StringUtils;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@@ -51,7 +52,7 @@ public boolean isSupport(String key, String value) {
public IRule createLoadBalancerRule(String ruleName) {
IRule rule;
try {
- rule = (IRule) Class.forName(ruleName, true,
Thread.currentThread().getContextClassLoader()).newInstance();
+ rule = (IRule) Class.forName(ruleName, true,
JvmUtils.findClassLoader()).newInstance();
} catch (InstantiationException | IllegalAccessException |
ClassNotFoundException e) {
LOGGER.warn("Loadbalance rule [{}] is incorrect, using default
RoundRobinRule.", ruleName);
rule = new RoundRobinRule();
diff --git
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/SwaggerGenerator.java
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/SwaggerGenerator.java
index 983f86fc9..aa472fd25 100644
---
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/SwaggerGenerator.java
+++
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/SwaggerGenerator.java
@@ -30,6 +30,7 @@
import javax.ws.rs.core.MediaType;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.springframework.util.StringUtils;
import io.swagger.annotations.Api;
@@ -80,7 +81,7 @@ public SwaggerGenerator(SwaggerGeneratorContext context,
Class<?> cls) {
this.swagger = new Swagger();
this.context = context;
this.cls = cls;
- this.classLoader = Thread.currentThread().getContextClassLoader();
+ this.classLoader = JvmUtils.findClassLoader();
this.packageName = "gen.swagger";
}
diff --git
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ClassUtils.java
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ClassUtils.java
index dbf79055d..ae7b7ada5 100644
---
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ClassUtils.java
+++
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ClassUtils.java
@@ -26,6 +26,7 @@
import org.apache.servicecomb.common.javassist.ClassConfig;
import org.apache.servicecomb.common.javassist.JavassistUtils;
+import org.apache.servicecomb.foundation.common.utils.JvmUtils;
import org.apache.servicecomb.swagger.converter.ConverterMgr;
import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator;
import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
@@ -43,9 +44,7 @@ private ClassUtils() {
}
public static Class<?> getClassByName(ClassLoader classLoader, String
clsName) {
- if (classLoader == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- }
+ classLoader = JvmUtils.correctClassLoader(classLoader);
try {
return classLoader.loadClass(clsName);
} catch (ClassNotFoundException e) {
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> Working in thread that do not have context class loader
> -------------------------------------------------------
>
> Key: SCB-715
> URL: https://issues.apache.org/jira/browse/SCB-715
> Project: Apache ServiceComb
> Issue Type: Improvement
> Reporter: liubao
> Assignee: liubao
> Priority: Major
>
> In some scenarios, context class loader may be null, e.g.
> executed in jvm parallel api, like Instream.rang(0,100).parallel
> context. The context class loader may be null.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)