From 2b0af38bc065b92ec23858eb721a28d208542696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B0=E9=9C=96?= Date: Sun, 22 Dec 2024 16:22:09 +0800 Subject: [PATCH 1/4] fix: hessian deserialize support sofa.serialize.dynamic.load.enable --- ...ingleClassLoaderSofaSerializerFactory.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java index d79ddf610..d0870cb65 100644 --- a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java +++ b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java @@ -27,6 +27,9 @@ import com.caucho.hessian.io.Serializer; import com.caucho.hessian.io.SerializerFactory; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import static com.alipay.hessian.generic.io.GenericDeserializer.ARRAY_PREFIX; import static com.alipay.sofa.rpc.codec.sofahessian.serialize.GenericCustomThrowableDeterminer.isGenericThrowException; @@ -43,6 +46,13 @@ public class SingleClassLoaderSofaSerializerFactory extends SerializerFactory { private static final Logger LOGGER = LoggerFactory .getLogger(SingleClassLoaderSofaSerializerFactory.class); + private Map> _typeNotFoundMap = new ConcurrentHashMap>( + 8); + private static final Object NOT_FOUND = new Object(); + private boolean dynamicLoadEnable = Boolean.parseBoolean(System.getProperty( + DYNAMIC_LOAD_ENABLE_KEY, + Boolean.FALSE.toString())); + @Override protected Serializer getDefaultSerializer(Class cl) { if (_defaultSerializer != null) { @@ -73,12 +83,33 @@ public Deserializer getDeserializer(String type) throws HessianProtocolException Deserializer subDeserializer = getDeserializer(type.substring(1)); deserializer = new ArrayDeserializer(subDeserializer); } else { + ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader(); try { - ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader(); + if (!dynamicLoadEnable) { + Map typeMap = _typeNotFoundMap.get(appClassLoader); + if (typeMap != null) { + if (typeMap.containsKey(type)) { + return null; + } + } + } Class cl = Class.forName(type, true, appClassLoader); deserializer = getDeserializer(cl); } catch (Exception e) { if (e instanceof ClassNotFoundException) { + if (!dynamicLoadEnable) { + Map typeMap = _typeNotFoundMap.get(appClassLoader); + if (typeMap == null) { + synchronized (this) { + typeMap = _typeNotFoundMap.get(appClassLoader); + if (typeMap == null) { + _typeNotFoundMap.put(appClassLoader, new ConcurrentHashMap(8)); + typeMap = _typeNotFoundMap.get(appClassLoader); + } + } + } + typeMap.put(type, NOT_FOUND); + } LOGGER.errorWithApp(null, LogCodes.getLog(LogCodes.ERROR_DECODE_CLASS_NOT_FOUND, getClass().getName(), type, Thread.currentThread().getContextClassLoader())); } else { From f8015f6537eed1e758cb3b5813d2526d976cb2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B0=E9=9C=96?= Date: Thu, 26 Dec 2024 15:07:50 +0800 Subject: [PATCH 2/4] fix: use computeIfAbsent to avoid using synchronized --- .../SingleClassLoaderSofaSerializerFactory.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java index d0870cb65..ee1de0c6f 100644 --- a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java +++ b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java @@ -98,17 +98,7 @@ public Deserializer getDeserializer(String type) throws HessianProtocolException } catch (Exception e) { if (e instanceof ClassNotFoundException) { if (!dynamicLoadEnable) { - Map typeMap = _typeNotFoundMap.get(appClassLoader); - if (typeMap == null) { - synchronized (this) { - typeMap = _typeNotFoundMap.get(appClassLoader); - if (typeMap == null) { - _typeNotFoundMap.put(appClassLoader, new ConcurrentHashMap(8)); - typeMap = _typeNotFoundMap.get(appClassLoader); - } - } - } - typeMap.put(type, NOT_FOUND); + _typeNotFoundMap.computeIfAbsent(appClassLoader, k -> new ConcurrentHashMap<>(8)).put(type, NOT_FOUND); } LOGGER.errorWithApp(null, LogCodes.getLog(LogCodes.ERROR_DECODE_CLASS_NOT_FOUND, getClass().getName(), type, Thread.currentThread().getContextClassLoader())); From 9785dc838fa4f11cce00633f7bcd2af8222a21fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B0=E9=9C=96?= Date: Thu, 26 Dec 2024 19:25:48 +0800 Subject: [PATCH 3/4] add test for sofa.serialize.dynamic.load.enable --- ...eClassLoaderSofaSerializerFactoryTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java b/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java index 727f1ff0b..4545e44c9 100644 --- a/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java +++ b/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java @@ -16,13 +16,17 @@ */ package com.alipay.sofa.rpc.codec.sofahessian; +import com.caucho.hessian.io.Deserializer; import com.caucho.hessian.io.Hessian2Input; import com.caucho.hessian.io.Hessian2Output; +import com.caucho.hessian.io.SerializerFactory; +import org.junit.Assert; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -63,4 +67,34 @@ public void testAll() throws IOException { assertEquals(a1[i], a2[i]); } + @Test + public void testDynamicLoadDisabled() throws Exception { + SingleClassLoaderSofaSerializerFactory factory = new SingleClassLoaderSofaSerializerFactory(); + Field field = SingleClassLoaderSofaSerializerFactory.class.getDeclaredField("_typeNotFoundMap"); + field.setAccessible(true); + Map> _typeNotFoundMap = (Map>) field.get(factory); + Assert.assertEquals(0, _typeNotFoundMap.size()); + Deserializer deserializer = factory.getDeserializer("mock.xxx.MockObject"); + Assert.assertNull(deserializer); + Assert.assertEquals(1, _typeNotFoundMap.size()); + } + + @Test + public void testDynamicLoadEnabled() throws Exception { + try { + System.setProperty(SerializerFactory.DYNAMIC_LOAD_ENABLE_KEY, "true"); + SingleClassLoaderSofaSerializerFactory factory = new SingleClassLoaderSofaSerializerFactory(); + Field field = SingleClassLoaderSofaSerializerFactory.class.getDeclaredField("_typeNotFoundMap"); + field.setAccessible(true); + Map> _typeNotFoundMap = (Map>) field.get(factory); + Assert.assertEquals(0, _typeNotFoundMap.size()); + Deserializer deserializer = factory.getDeserializer("mock.xxx.MockObject"); + Assert.assertNull(deserializer); + Assert.assertEquals(0, _typeNotFoundMap.size()); + } + finally { + System.clearProperty(SerializerFactory.DYNAMIC_LOAD_ENABLE_KEY); + } + } + } \ No newline at end of file From d9745e6e86920d4db5bd15000480aabafa27758a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=B0=E9=9C=96?= Date: Thu, 26 Dec 2024 19:28:53 +0800 Subject: [PATCH 4/4] format code --- ...SingleClassLoaderSofaSerializerFactory.java | 18 +++++++++--------- ...leClassLoaderSofaSerializerFactoryTest.java | 9 +++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java index ee1de0c6f..bf9ac200c 100644 --- a/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java +++ b/codec/codec-sofa-hessian/src/main/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactory.java @@ -43,15 +43,15 @@ public class SingleClassLoaderSofaSerializerFactory extends SerializerFactory { /** * logger for this class */ - private static final Logger LOGGER = LoggerFactory - .getLogger(SingleClassLoaderSofaSerializerFactory.class); - - private Map> _typeNotFoundMap = new ConcurrentHashMap>( - 8); - private static final Object NOT_FOUND = new Object(); - private boolean dynamicLoadEnable = Boolean.parseBoolean(System.getProperty( - DYNAMIC_LOAD_ENABLE_KEY, - Boolean.FALSE.toString())); + private static final Logger LOGGER = LoggerFactory + .getLogger(SingleClassLoaderSofaSerializerFactory.class); + + private Map> _typeNotFoundMap = new ConcurrentHashMap>( + 8); + private static final Object NOT_FOUND = new Object(); + private boolean dynamicLoadEnable = Boolean.parseBoolean(System.getProperty( + DYNAMIC_LOAD_ENABLE_KEY, + Boolean.FALSE.toString())); @Override protected Serializer getDefaultSerializer(Class cl) { diff --git a/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java b/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java index 4545e44c9..26bef4434 100644 --- a/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java +++ b/codec/codec-sofa-hessian/src/test/java/com/alipay/sofa/rpc/codec/sofahessian/SingleClassLoaderSofaSerializerFactoryTest.java @@ -72,7 +72,8 @@ public void testDynamicLoadDisabled() throws Exception { SingleClassLoaderSofaSerializerFactory factory = new SingleClassLoaderSofaSerializerFactory(); Field field = SingleClassLoaderSofaSerializerFactory.class.getDeclaredField("_typeNotFoundMap"); field.setAccessible(true); - Map> _typeNotFoundMap = (Map>) field.get(factory); + Map> _typeNotFoundMap = (Map>) field + .get(factory); Assert.assertEquals(0, _typeNotFoundMap.size()); Deserializer deserializer = factory.getDeserializer("mock.xxx.MockObject"); Assert.assertNull(deserializer); @@ -86,13 +87,13 @@ public void testDynamicLoadEnabled() throws Exception { SingleClassLoaderSofaSerializerFactory factory = new SingleClassLoaderSofaSerializerFactory(); Field field = SingleClassLoaderSofaSerializerFactory.class.getDeclaredField("_typeNotFoundMap"); field.setAccessible(true); - Map> _typeNotFoundMap = (Map>) field.get(factory); + Map> _typeNotFoundMap = (Map>) field + .get(factory); Assert.assertEquals(0, _typeNotFoundMap.size()); Deserializer deserializer = factory.getDeserializer("mock.xxx.MockObject"); Assert.assertNull(deserializer); Assert.assertEquals(0, _typeNotFoundMap.size()); - } - finally { + } finally { System.clearProperty(SerializerFactory.DYNAMIC_LOAD_ENABLE_KEY); } }