Merge pull request #7 from hopelove404/hessian-optimize-typenotfound
Fix performance overhead caused by too much unknown classloading during hessian2 deserialization
diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java b/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java
index b233fdb..5459718 100644
--- a/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java
+++ b/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java
@@ -70,15 +70,7 @@
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -231,6 +223,12 @@
private ConcurrentHashMap _cachedDeserializerMap;
private ConcurrentHashMap _cachedTypeDeserializerMap;
private boolean _isAllowNonSerializable;
+ /**
+ * For those classes are unknown in current classloader, record them in this set to avoid
+ * frequently class loading and to reduce performance overhead.
+ */
+ private Map<String, Object> _typeNotFoundDeserializerMap = new ConcurrentHashMap<>(8);
+ private static final Object PRESENT = new Object();
public SerializerFactory() {
this(Thread.currentThread().getContextClassLoader());
@@ -617,7 +615,7 @@
*/
public Deserializer getDeserializer(String type)
throws HessianProtocolException {
- if (type == null || type.equals(""))
+ if (type == null || type.equals("") || _typeNotFoundDeserializerMap.containsKey(type))
return null;
Deserializer deserializer;
@@ -647,7 +645,7 @@
deserializer = getDeserializer(cl);
} catch (Exception e) {
log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + _loader + ":\n" + e);
-
+ _typeNotFoundDeserializerMap.put(type, PRESENT);
log.log(Level.FINER, e.toString(), e);
}
}
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/SerializerFactoryTest.java b/src/test/java/com/alibaba/com/caucho/hessian/io/SerializerFactoryTest.java
index 652f8ef..36b32c5 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/SerializerFactoryTest.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/SerializerFactoryTest.java
@@ -99,4 +99,18 @@
countDownLatch.await();
}
+ @Test
+ public void getDeserializerByType() throws Exception {
+ final SerializerFactory serializerFactory = new SerializerFactory();
+
+ final String testClassName = TestClass.class.getName();
+ Deserializer d1 = serializerFactory.getDeserializer(testClassName);
+ Assert.assertTrue("TestClass Deserializer!", d1 != null);
+
+ Deserializer d2 = serializerFactory.getDeserializer("com.test.NotExistClass");
+ Assert.assertTrue("NotExistClass Deserializer!", d2 == null);
+ //again check NotExistClass, there should be no warning like Hessian/Burlap:.....
+ Deserializer d3 = serializerFactory.getDeserializer("com.test.NotExistClass");
+ Assert.assertTrue("NotExistClass Deserializer!", d3 == null);
+ }
}
\ No newline at end of file