From dad55714caff3c03a0c5a806ae35e84e58ea1b3b Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Tue, 26 Sep 2023 10:44:07 +0800 Subject: [PATCH] Fix Hessian Serializer Factory concurrent issue (#13122) --- .../hessian2/Hessian2FactoryManager.java | 33 +++++++------------ .../hessian2/Hessian2SerializerFactory.java | 4 ++- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java index 8391ff2f09..dbd595bcd5 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java @@ -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 CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>(); + private final ConcurrentHashMap 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); diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java index 893e1a59c6..b6bf38fbe0 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java @@ -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; }