Fix Hessian Serializer Factory concurrent issue (#13122)

This commit is contained in:
Albumen Kevin 2023-09-26 10:44:07 +08:00 committed by GitHub
parent 327b808689
commit dad55714ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 22 deletions

View File

@ -16,6 +16,7 @@
*/
package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
import org.apache.dubbo.common.utils.DefaultSerializeClassChecker;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
@ -24,7 +25,6 @@ import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -34,7 +34,7 @@ public class Hessian2FactoryManager {
String DENY = "dubbo.application.hessian2.deny";
private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
private volatile SerializerFactory stickySerializerFactory = null;
private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private final ConcurrentHashMap<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private final SerializeSecurityManager serializeSecurityManager;
private final DefaultSerializeClassChecker defaultSerializeClassChecker;
@ -55,7 +55,7 @@ public class Hessian2FactoryManager {
if (SYSTEM_SERIALIZER_FACTORY == null) {
synchronized (this) {
if (SYSTEM_SERIALIZER_FACTORY == null) {
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory(null);
}
}
}
@ -63,39 +63,30 @@ public class Hessian2FactoryManager {
return SYSTEM_SERIALIZER_FACTORY;
}
SerializerFactory factory = CL_2_SERIALIZER_FACTORY.get(classLoader);
if (factory == null) {
synchronized (this) {
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
SerializerFactory serializerFactory = createSerializerFactory();
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
stickySerializerFactory = serializerFactory;
return serializerFactory;
}
}
}
SerializerFactory factory = ConcurrentHashMapUtils.computeIfAbsent(CL_2_SERIALIZER_FACTORY,
classLoader, this::createSerializerFactory);
stickySerializerFactory = factory;
return factory;
}
private SerializerFactory createSerializerFactory() {
private SerializerFactory createSerializerFactory(ClassLoader classLoader) {
String whitelist = System.getProperty(WHITELIST);
if (StringUtils.isNotEmpty(whitelist)) {
return createWhiteListSerializerFactory();
return createWhiteListSerializerFactory(classLoader);
}
return createDefaultSerializerFactory();
return createDefaultSerializerFactory(classLoader);
}
private SerializerFactory createDefaultSerializerFactory() {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(defaultSerializeClassChecker);
private SerializerFactory createDefaultSerializerFactory(ClassLoader classLoader) {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(classLoader, defaultSerializeClassChecker);
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return hessian2SerializerFactory;
}
public SerializerFactory createWhiteListSerializerFactory() {
SerializerFactory serializerFactory = new Hessian2SerializerFactory(defaultSerializeClassChecker);
public SerializerFactory createWhiteListSerializerFactory(ClassLoader classLoader) {
SerializerFactory serializerFactory = new Hessian2SerializerFactory(classLoader, defaultSerializeClassChecker);
String whiteList = System.getProperty(WHITELIST);
if ("true".equals(whiteList)) {
serializerFactory.getClassFactory().setWhitelist(true);

View File

@ -30,7 +30,9 @@ public class Hessian2SerializerFactory extends SerializerFactory {
private final DefaultSerializeClassChecker defaultSerializeClassChecker;
public Hessian2SerializerFactory(DefaultSerializeClassChecker defaultSerializeClassChecker) {
public Hessian2SerializerFactory(ClassLoader classLoader, DefaultSerializeClassChecker defaultSerializeClassChecker) {
super(classLoader);
this.defaultSerializeClassChecker = defaultSerializeClassChecker;
}