This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 2.6.x
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/2.6.x by this push:
     new b100a6d  [2.6.X]Add some serialize check (#7685)
b100a6d is described below

commit b100a6d22b5cf051f76dad2b05aaf88e74e22154
Author: Wu Zhiguo <[email protected]>
AuthorDate: Thu May 13 12:13:42 2021 +0800

    [2.6.X]Add some serialize check (#7685)
    
    * fix security problem
    
    * use Boolean.parseBoolean to check system env
    
    * ignore '#' when parsing url
    
    * fix url was truncated expectedly
    
    * fix ut
    
    * fix ut
---
 .../rpc/cluster/router/script/ScriptRouter.java    | 125 ++++++---
 .../com.alibaba.dubbo.rpc.cluster.RouterFactory    |   1 -
 .../com.alibaba.dubbo.rpc.cluster.RouterFactory    |   1 +
 .../java/com/alibaba/dubbo/common/Constants.java   |  15 +-
 .../main/java/com/alibaba/dubbo/common/URL.java    |   7 +
 .../common/beanutil/JavaBeanSerializeUtil.java     |   2 +
 .../com/alibaba/dubbo/common/utils/LFUCache.java   | 286 +++++++++++++++++++++
 .../com/alibaba/dubbo/common/utils/PojoUtils.java  |   1 +
 .../dubbo/common/utils/SerializeClassChecker.java  | 150 +++++++++++
 .../alibaba/dubbo/common/utils/StringUtils.java    |   8 +
 .../main/resources/security/serialize.blockedlist  | 167 ++++++++++++
 dubbo-config/dubbo-config-api/pom.xml              |   5 +
 .../alibaba/dubbo/config/GenericServiceTest.java   |   6 +
 .../com.alibaba.dubbo.rpc.cluster.RouterFactory    |   1 +
 .../alibaba/dubbo/rpc/filter/GenericFilter.java    |  19 ++
 .../protocol/dubbo/DubboInvokerAvilableTest.java   |   8 +-
 .../rpc/protocol/hessian/HessianProtocolTest.java  |  10 +
 .../dubbo/rpc/protocol/http/HttpProtocolTest.java  |   7 +
 18 files changed, 784 insertions(+), 35 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java
 
b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java
index 89241ad..700abbd 100644
--- 
a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java
+++ 
b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java
@@ -20,6 +20,7 @@ import com.alibaba.dubbo.common.Constants;
 import com.alibaba.dubbo.common.URL;
 import com.alibaba.dubbo.common.logger.Logger;
 import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.utils.StringUtils;
 import com.alibaba.dubbo.rpc.Invocation;
 import com.alibaba.dubbo.rpc.Invoker;
 import com.alibaba.dubbo.rpc.RpcContext;
@@ -32,6 +33,13 @@ import javax.script.CompiledScript;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -53,17 +61,51 @@ public class ScriptRouter extends AbstractRouter {
 
     private final String rule;
 
+    private CompiledScript function;
+
+    private AccessControlContext accessControlContext;
+
+    {
+        //Just give permission of reflect to access member.
+        Permissions perms = new Permissions();
+        perms.add(new RuntimePermission("accessDeclaredMembers"));
+        // Cast to Certificate[] required because of ambiguity:
+        ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, 
(Certificate[]) null), perms);
+        accessControlContext = new AccessControlContext(new 
ProtectionDomain[]{domain});
+    }
+
     public ScriptRouter(URL url) {
         this.url = url;
-        String type = url.getParameter(Constants.TYPE_KEY);
         this.priority = url.getParameter(Constants.PRIORITY_KEY, 
DEFAULT_PRIORITY);
-        String rule = url.getParameterAndDecoded(Constants.RULE_KEY);
-        if (type == null || type.length() == 0) {
-            type = Constants.DEFAULT_SCRIPT_TYPE_KEY;
+
+        this.engine = getEngine(url);
+        this.rule = getRule(url);
+
+        try {
+            Compilable compilable = (Compilable) engine;
+            function = compilable.compile(rule);
+        } catch (ScriptException e) {
+            logger.error("route error, rule has been ignored. rule: " + rule +
+                    ", url: " + RpcContext.getContext().getUrl(), e);
         }
-        if (rule == null || rule.length() == 0) {
-            throw new IllegalStateException(new IllegalStateException("route 
rule can not be empty. rule:" + rule));
+    }
+
+    /**
+     * get rule from url parameters.
+     */
+    private String getRule(URL url) {
+        String vRule = url.getParameterAndDecoded(Constants.RULE_KEY);
+        if (StringUtils.isEmpty(vRule)) {
+            throw new IllegalStateException("route rule can not be empty.");
         }
+        return vRule;
+    }
+
+    /**
+     * create ScriptEngine instance by type from url parameters, then cache it
+     */
+    private ScriptEngine getEngine(URL url) {
+        String type = url.getParameter(Constants.TYPE_KEY, 
Constants.DEFAULT_SCRIPT_TYPE_KEY);
         ScriptEngine engine = engines.get(type);
         if (engine == null) {
             engine = new ScriptEngineManager().getEngineByName(type);
@@ -72,38 +114,61 @@ public class ScriptRouter extends AbstractRouter {
             }
             engines.put(type, engine);
         }
-        this.engine = engine;
-        this.rule = rule;
+
+        return engine;
     }
 
+
     @Override
     @SuppressWarnings("unchecked")
-    public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, 
Invocation invocation) throws RpcException {
-        try {
-            List<Invoker<T>> invokersCopy = new 
ArrayList<Invoker<T>>(invokers);
-            Compilable compilable = (Compilable) engine;
-            Bindings bindings = engine.createBindings();
-            bindings.put("invokers", invokersCopy);
-            bindings.put("invocation", invocation);
-            bindings.put("context", RpcContext.getContext());
-            CompiledScript function = compilable.compile(rule);
-            Object obj = function.eval(bindings);
-            if (obj instanceof Invoker[]) {
-                invokersCopy = Arrays.asList((Invoker<T>[]) obj);
-            } else if (obj instanceof Object[]) {
-                invokersCopy = new ArrayList<Invoker<T>>();
-                for (Object inv : (Object[]) obj) {
-                    invokersCopy.add((Invoker<T>) inv);
+    public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers, URL 
url, final Invocation invocation) throws RpcException {
+        if (engine == null || function == null) {
+            return invokers;
+        }
+        final Bindings bindings = createBindings(invokers, invocation);
+        return getRoutedInvokers(AccessController.doPrivileged(new 
PrivilegedAction() {
+            @Override
+            public Object run() {
+                try {
+                    return function.eval(bindings);
+                } catch (ScriptException e) {
+                    logger.error("route error, rule has been ignored. rule: " 
+ rule + ", method:" +
+                            invocation.getMethodName() + ", url: " + 
RpcContext.getContext().getUrl(), e);
+                    return invokers;
                 }
-            } else {
-                invokersCopy = (List<Invoker<T>>) obj;
             }
-            return invokersCopy;
-        } catch (ScriptException e) {
-            //fail then ignore rule .invokers.
-            logger.error("route error , rule has been ignored. rule: " + rule 
+ ", method:" + invocation.getMethodName() + ", url: " + 
RpcContext.getContext().getUrl(), e);
+        }, accessControlContext));
+    }
+
+    /**
+     * get routed invokers from result of script rule evaluation
+     */
+    @SuppressWarnings("unchecked")
+    protected <T> List<Invoker<T>> getRoutedInvokers(Object obj) {
+        if (obj instanceof Invoker[]) {
+            return Arrays.asList((Invoker<T>[]) obj);
+        } else if (obj instanceof Object[]) {
+            Object[] objects = (Object[]) obj;
+            List<Invoker<T>> invokers = new ArrayList<Invoker<T>>();
+            for (Object object : objects) {
+                invokers.add((Invoker<T>) object);
+            }
+
             return invokers;
+        } else {
+            return (List<Invoker<T>>) obj;
         }
     }
 
+    /**
+     * create bindings for script engine
+     */
+    private <T> Bindings createBindings(List<Invoker<T>> invokers, Invocation 
invocation) {
+        Bindings bindings = engine.createBindings();
+        // create a new List of invokers
+        bindings.put("invokers", new ArrayList<Invoker<T>>(invokers));
+        bindings.put("invocation", invocation);
+        bindings.put("context", RpcContext.getContext());
+        return bindings;
+    }
 }
diff --git 
a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
 
b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
index 239c6f0..efa0123 100644
--- 
a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
+++ 
b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
@@ -1,3 +1,2 @@
 file=com.alibaba.dubbo.rpc.cluster.router.file.FileRouterFactory
-script=com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory
 condition=com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouterFactory
\ No newline at end of file
diff --git 
a/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
 
b/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
new file mode 100644
index 0000000..a7f6ddc
--- /dev/null
+++ 
b/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
@@ -0,0 +1 @@
+script=com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
index 126319f..0bb2b2e 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
@@ -647,8 +647,17 @@ public class Constants {
 
     public static final String TELNET = "telnet";
 
-    /*
-     * private Constants(){ }
-     */
+    public static final String DOT_REGEX = "\\.";
+
+    public static final String UNDERLINE_SEPARATOR = "_";
+
+    public static final String CLASS_DESERIALIZE_BLOCK_ALL = 
"dubbo.security.serialize.blockAllClassExceptAllow";
+
+    public static final String CLASS_DESERIALIZE_ALLOWED_LIST = 
"dubbo.security.serialize.allowedClassList";
+
+    public static final String CLASS_DESERIALIZE_BLOCKED_LIST = 
"dubbo.security.serialize.blockedClassList";
+
+    public static final String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = 
"dubbo.security.serialize.generic.native-java-enable";
 
+    public static final String SERIALIZE_BLOCKED_LIST_FILE_PATH = 
"security/serialize.blockedlist";
 }
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/URL.java 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/URL.java
index f8a1119..f49aa55 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/URL.java
@@ -204,6 +204,13 @@ public final class URL implements Serializable {
             }
             url = url.substring(0, i);
         }
+
+        // ignore the url content following '#'
+        int poundIndex = url.indexOf('#');
+        if (poundIndex != -1) {
+            url = url.substring(0, poundIndex);
+        }
+
         i = url.indexOf("://");
         if (i >= 0) {
             if (i == 0) throw new IllegalStateException("url missing protocol: 
\"" + url + "\"");
diff --git 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanSerializeUtil.java
 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanSerializeUtil.java
index d89f4c0..643f0ca 100644
--- 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanSerializeUtil.java
+++ 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/beanutil/JavaBeanSerializeUtil.java
@@ -20,6 +20,7 @@ import com.alibaba.dubbo.common.logger.Logger;
 import com.alibaba.dubbo.common.logger.LoggerFactory;
 import com.alibaba.dubbo.common.utils.LogHelper;
 import com.alibaba.dubbo.common.utils.ReflectUtils;
+import com.alibaba.dubbo.common.utils.SerializeClassChecker;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
@@ -439,6 +440,7 @@ public final class JavaBeanSerializeUtil {
         if (isReferenceType(name)) {
             name = name.substring(1, name.length() - 1);
         }
+        SerializeClassChecker.getInstance().validateClass(name);
         return Class.forName(name, false, loader);
     }
 
diff --git 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/LFUCache.java 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/LFUCache.java
new file mode 100644
index 0000000..75441c9
--- /dev/null
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/LFUCache.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.common.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class LFUCache<K, V> {
+
+    private Map<K, CacheNode<K, V>> map;
+    private CacheDeque<K, V>[] freqTable;
+
+    private final int capacity;
+    private int evictionCount;
+    private int curSize = 0;
+
+    private final ReentrantLock lock = new ReentrantLock();
+    private static final int DEFAULT_INITIAL_CAPACITY = 1000;
+
+    private static final float DEFAULT_EVICTION_FACTOR = 0.75f;
+
+    public LFUCache() {
+        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_EVICTION_FACTOR);
+    }
+
+    /**
+     * Constructs and initializes cache with specified capacity and eviction
+     * factor. Unacceptable parameter values followed with
+     * {@link IllegalArgumentException}.
+     *
+     * @param maxCapacity    cache max capacity
+     * @param evictionFactor cache proceedEviction factor
+     */
+    @SuppressWarnings("unchecked")
+    public LFUCache(final int maxCapacity, final float evictionFactor) {
+        if (maxCapacity <= 0) {
+            throw new IllegalArgumentException("Illegal initial capacity: " +
+                    maxCapacity);
+        }
+        boolean factorInRange = evictionFactor <= 1 && evictionFactor > 0;
+        if (!factorInRange || Float.isNaN(evictionFactor)) {
+            throw new IllegalArgumentException("Illegal eviction factor value:"
+                    + evictionFactor);
+        }
+        this.capacity = maxCapacity;
+        this.evictionCount = (int) (capacity * evictionFactor);
+        this.map = new HashMap<K, CacheNode<K, V>>();
+        this.freqTable = new CacheDeque[capacity + 1];
+        for (int i = 0; i <= capacity; i++) {
+            freqTable[i] = new CacheDeque<K, V>();
+        }
+        for (int i = 0; i < capacity; i++) {
+            freqTable[i].nextDeque = freqTable[i + 1];
+        }
+        freqTable[capacity].nextDeque = freqTable[capacity];
+    }
+
+    public int getCapacity() {
+        return capacity;
+    }
+
+    public V put(final K key, final V value) {
+        CacheNode<K, V> node;
+        lock.lock();
+        try {
+            node = map.get(key);
+            if (node != null) {
+                CacheNode.withdrawNode(node);
+                node.value = value;
+                freqTable[0].addLastNode(node);
+                map.put(key, node);
+            } else {
+                node = freqTable[0].addLast(key, value);
+                map.put(key, node);
+                curSize++;
+                if (curSize > capacity) {
+                    proceedEviction();
+                }
+            }
+        } finally {
+            lock.unlock();
+        }
+        return node.value;
+    }
+
+    public V remove(final K key) {
+        CacheNode<K, V> node = null;
+        lock.lock();
+        try {
+            if (map.containsKey(key)) {
+                node = map.remove(key);
+                if (node != null) {
+                    CacheNode.withdrawNode(node);
+                }
+                curSize--;
+            }
+        } finally {
+            lock.unlock();
+        }
+        return (node != null) ? node.value : null;
+    }
+
+    public V get(final K key) {
+        CacheNode<K, V> node = null;
+        lock.lock();
+        try {
+            if (map.containsKey(key)) {
+                node = map.get(key);
+                CacheNode.withdrawNode(node);
+                node.owner.nextDeque.addLastNode(node);
+            }
+        } finally {
+            lock.unlock();
+        }
+        return (node != null) ? node.value : null;
+    }
+
+    /**
+     * Evicts less frequently used elements corresponding to eviction factor,
+     * specified at instantiation step.
+     *
+     * @return number of evicted elements
+     */
+    private int proceedEviction() {
+        int targetSize = capacity - evictionCount;
+        int evictedElements = 0;
+
+        FREQ_TABLE_ITER_LOOP:
+        for (int i = 0; i <= capacity; i++) {
+            CacheNode<K, V> node;
+            while (!freqTable[i].isEmpty()) {
+                node = freqTable[i].pollFirst();
+                remove(node.key);
+                if (targetSize >= curSize) {
+                    break FREQ_TABLE_ITER_LOOP;
+                }
+                evictedElements++;
+            }
+        }
+        return evictedElements;
+    }
+
+    /**
+     * Returns cache current size.
+     *
+     * @return cache size
+     */
+    public int getSize() {
+        return curSize;
+    }
+
+    static class CacheNode<K, V> {
+
+        CacheNode<K, V> prev;
+        CacheNode<K, V> next;
+        K key;
+        V value;
+        CacheDeque<K, V> owner;
+
+        CacheNode() {
+        }
+
+        CacheNode(final K key, final V value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        /**
+         * This method takes specified node and reattaches it neighbors nodes
+         * links to each other, so specified node will no longer tied with 
them.
+         * Returns united node, returns null if argument is null.
+         *
+         * @param node note to retrieve
+         * @param <K>  key
+         * @param <V>  value
+         * @return retrieved node
+         */
+        static <K, V> CacheNode<K, V> withdrawNode(
+                final CacheNode<K, V> node) {
+            if (node != null && node.prev != null) {
+                node.prev.next = node.next;
+                if (node.next != null) {
+                    node.next.prev = node.prev;
+                }
+            }
+            return node;
+        }
+
+    }
+
+    /**
+     * Custom deque implementation of LIFO type. Allows to place element at top
+     * of deque and poll very last added elements. An arbitrary node from the
+     * deque can be removed with {@link CacheNode#withdrawNode(CacheNode)}
+     * method.
+     *
+     * @param <K> key
+     * @param <V> value
+     */
+    static class CacheDeque<K, V> {
+
+        CacheNode<K, V> last;
+        CacheNode<K, V> first;
+        CacheDeque<K, V> nextDeque;
+
+        /**
+         * Constructs list and initializes last and first pointers.
+         */
+        CacheDeque() {
+            last = new CacheNode<K, V>();
+            first = new CacheNode<K, V>();
+            last.next = first;
+            first.prev = last;
+        }
+
+        /**
+         * Puts the node with specified key and value at the end of the deque
+         * and returns node.
+         *
+         * @param key   key
+         * @param value value
+         * @return added node
+         */
+        CacheNode<K, V> addLast(final K key, final V value) {
+            CacheNode<K, V> node = new CacheNode<K, V>(key, value);
+            node.owner = this;
+            node.next = last.next;
+            node.prev = last;
+            node.next.prev = node;
+            last.next = node;
+            return node;
+        }
+
+        CacheNode<K, V> addLastNode(final CacheNode<K, V> node) {
+            node.owner = this;
+            node.next = last.next;
+            node.prev = last;
+            node.next.prev = node;
+            last.next = node;
+            return node;
+        }
+
+        /**
+         * Retrieves and removes the first node of this deque.
+         *
+         * @return removed node
+         */
+        CacheNode<K, V> pollFirst() {
+            CacheNode<K, V> node = null;
+            if (first.prev != last) {
+                node = first.prev;
+                first.prev = node.prev;
+                first.prev.next = first;
+                node.prev = null;
+                node.next = null;
+            }
+            return node;
+        }
+
+        /**
+         * Checks if link to the last node points to link to the first node.
+         *
+         * @return is deque empty
+         */
+        boolean isEmpty() {
+            return last.next == first;
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java
index 754fd2d..f069151 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java
@@ -371,6 +371,7 @@ public class PojoUtils {
         if (pojo instanceof Map<?, ?> && type != null) {
             Object className = ((Map<Object, Object>) pojo).get("class");
             if (className instanceof String) {
+                SerializeClassChecker.getInstance().validateClass((String) 
className);
                 try {
                     type = ClassHelper.forName((String) className);
                 } catch (ClassNotFoundException e) {
diff --git 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/SerializeClassChecker.java
 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/SerializeClassChecker.java
new file mode 100644
index 0000000..fc19223
--- /dev/null
+++ 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/SerializeClassChecker.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.common.utils;
+
+import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class SerializeClassChecker {
+    private static final Logger logger = 
LoggerFactory.getLogger(SerializeClassChecker.class);
+
+    private static volatile SerializeClassChecker INSTANCE = null;
+
+    private final boolean BLOCK_ALL_CLASS_EXCEPT_ALLOW;
+    private final Set<String> CLASS_DESERIALIZE_ALLOWED_SET = new 
ConcurrentHashSet<String>();
+    private final Set<String> CLASS_DESERIALIZE_BLOCKED_SET = new 
ConcurrentHashSet<String>();
+
+    private final Object CACHE = new Object();
+    private final LFUCache<String, Object> CLASS_ALLOW_LFU_CACHE = new 
LFUCache<String, Object>();
+    private final LFUCache<String, Object> CLASS_BLOCK_LFU_CACHE = new 
LFUCache<String, Object>();
+
+    private final AtomicLong counter = new AtomicLong(0);
+
+    private SerializeClassChecker() {
+        String blockAllClassExceptAllow = 
System.getProperty(Constants.CLASS_DESERIALIZE_BLOCK_ALL, "false");
+        BLOCK_ALL_CLASS_EXCEPT_ALLOW = 
Boolean.parseBoolean(blockAllClassExceptAllow);
+
+        String[] lines;
+        try {
+            ClassLoader classLoader = 
JavaBeanSerializeUtil.class.getClassLoader();
+            if (classLoader != null) {
+                lines = 
IOUtils.readLines(classLoader.getResourceAsStream(Constants.SERIALIZE_BLOCKED_LIST_FILE_PATH));
+            } else {
+                lines = 
IOUtils.readLines(ClassLoader.getSystemResourceAsStream(Constants.SERIALIZE_BLOCKED_LIST_FILE_PATH));
+            }
+            for (String line : lines) {
+                line = line.trim();
+                if (StringUtils.isEmpty(line) || line.startsWith("#")) {
+                    continue;
+                }
+                CLASS_DESERIALIZE_BLOCKED_SET.add(line);
+            }
+
+        } catch (IOException e) {
+            logger.error("Failed to load blocked class list! Will ignore 
default blocked list.", e);
+        }
+
+        String allowedClassList = 
System.getProperty(Constants.CLASS_DESERIALIZE_ALLOWED_LIST, 
"").trim().toLowerCase(Locale.ROOT);
+        String blockedClassList = 
System.getProperty(Constants.CLASS_DESERIALIZE_BLOCKED_LIST, 
"").trim().toLowerCase(Locale.ROOT);
+
+        if (StringUtils.isNotEmpty(allowedClassList)) {
+            String[] classStrings = allowedClassList.trim().split(",");
+            CLASS_DESERIALIZE_ALLOWED_SET.addAll(Arrays.asList(classStrings));
+        }
+
+        if (StringUtils.isNotEmpty(blockedClassList)) {
+            String[] classStrings = blockedClassList.trim().split(",");
+            CLASS_DESERIALIZE_BLOCKED_SET.addAll(Arrays.asList(classStrings));
+        }
+
+    }
+
+    public static SerializeClassChecker getInstance() {
+        if (INSTANCE == null) {
+            synchronized (SerializeClassChecker.class) {
+                if (INSTANCE == null) {
+                    INSTANCE = new SerializeClassChecker();
+                }
+            }
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * For ut only
+     */
+    @Deprecated
+    protected static void clearInstance() {
+        INSTANCE = null;
+    }
+
+    /**
+     * Check if a class is in block list, using prefix match
+     *
+     * @throws IllegalArgumentException if class is blocked
+     * @param name class name ( all are convert to lower case )
+     */
+    public void validateClass(String name) {
+        name = name.toLowerCase(Locale.ROOT);
+        if (CACHE == CLASS_ALLOW_LFU_CACHE.get(name)) {
+            return;
+        }
+
+        if (CACHE == CLASS_BLOCK_LFU_CACHE.get(name)) {
+            error(name);
+        }
+
+        for (String allowedPrefix : CLASS_DESERIALIZE_ALLOWED_SET) {
+            if (name.startsWith(allowedPrefix)) {
+                CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
+                return;
+            }
+        }
+
+        for (String blockedPrefix : CLASS_DESERIALIZE_BLOCKED_SET) {
+            if (BLOCK_ALL_CLASS_EXCEPT_ALLOW || 
name.startsWith(blockedPrefix)) {
+                CLASS_BLOCK_LFU_CACHE.put(name, CACHE);
+                error(name);
+            }
+        }
+
+        CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
+    }
+
+    private void error(String name) {
+        String notice = "Trigger the safety barrier! " +
+                "Catch not allowed serialize class. " +
+                "Class name: " + name + " . " +
+                "This means currently maybe being attacking by others." +
+                "If you are sure this is a mistake, " +
+                "please add this class name to `" + 
Constants.CLASS_DESERIALIZE_ALLOWED_LIST +
+                "` as a system environment property.";
+        if (counter.incrementAndGet() % 1000 == 0 || counter.get() < 100) {
+            logger.error(notice);
+        }
+        throw new IllegalArgumentException(notice);
+    }
+
+}
\ No newline at end of file
diff --git 
a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/StringUtils.java 
b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/StringUtils.java
index faf349f..d6a0e56 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/StringUtils.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/StringUtils.java
@@ -427,4 +427,12 @@ public final class StringUtils {
         }
         return buf.toString();
     }
+
+    public static String toOSStyleKey(String key) {
+        key = key.toUpperCase().replaceAll(Constants.DOT_REGEX, 
Constants.UNDERLINE_SEPARATOR);
+        if (!key.startsWith("DUBBO_")) {
+            key = "DUBBO_" + key;
+        }
+        return key;
+    }
 }
\ No newline at end of file
diff --git a/dubbo-common/src/main/resources/security/serialize.blockedlist 
b/dubbo-common/src/main/resources/security/serialize.blockedlist
new file mode 100644
index 0000000..de0b68d
--- /dev/null
+++ b/dubbo-common/src/main/resources/security/serialize.blockedlist
@@ -0,0 +1,167 @@
+#
+#
+#   Licensed to the Apache Software Foundation (ASF) under one or more
+#   contributor license agreements.  See the NOTICE file distributed with
+#   this work for additional information regarding copyright ownership.
+#   The ASF licenses this file to You under the Apache License, Version 2.0
+#   (the "License"); you may not use this file except in compliance with
+#   the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+#
+aj.org.objectweb.asm.
+br.com.anteros.
+ch.qos.logback.
+clojure.core$constantly
+clojure.main$eval_opt
+com.alibaba.citrus.springext.support.parser.abstractnamedproxybeandefinitionparser$proxytargetfactory
+com.alibaba.citrus.springext.util.springextutil.abstractproxy
+com.alibaba.druid.pool.druiddatasource
+com.alibaba.druid.stat.jdbcdatasourcestat
+com.alibaba.fastjson.annotation
+com.alipay.custrelation.service.model.redress.pair
+com.caucho.
+com.ibatis.
+com.mchange
+com.mysql.cj.jdbc.admin.
+com.mysql.cj.jdbc.mysqlconnectionpooldatasource
+com.mysql.cj.jdbc.mysqldatasource
+com.mysql.cj.jdbc.mysqlxadatasource
+com.mysql.cj.log.
+com.p6spy.engine.
+com.rometools.rome.feed.impl.equalsbean
+com.rometools.rome.feed.impl.tostringbean
+com.sun.
+com.taobao.eagleeye.wrapper
+com.zaxxer.hikari.
+flex.messaging.util.concurrent.
+java.awt.i
+java.awt.p
+java.beans.expression
+java.io.closeable
+java.io.serializable
+java.lang.autocloseable
+java.lang.class
+java.lang.cloneable
+java.lang.iterable
+java.lang.object
+java.lang.readable
+java.lang.runnable
+java.lang.thread
+java.lang.unixprocess
+java.net.inetaddress
+java.net.socket
+java.net.url
+java.rmi
+java.security.signedobject
+java.util.collection
+java.util.eventlistener
+java.util.jar.
+java.util.logging.
+java.util.prefs.
+java.util.serviceloader$lazyiterator
+javassist.
+javax.activation.
+javax.imageio.imageio$containsfilter
+javax.imageio.spi.serviceregistry
+javax.management.
+javax.naming.
+javax.net.
+javax.print.
+javax.script.
+javax.sound.
+javax.swing.j
+javax.tools.
+javax.xml
+jdk.internal.
+jodd.db.connection.
+junit.
+net.bytebuddy.dynamic.loading.bytearrayclassloader
+net.sf.cglib.
+net.sf.ehcache.hibernate.
+net.sf.ehcache.transaction.manager.
+oracle.jdbc.
+oracle.jms.aq
+oracle.net
+org.aoju.bus.proxy.provider.
+org.apache.activemq.activemqconnectionfactory
+org.apache.activemq.activemqxaconnectionfactory
+org.apache.activemq.jms.pool.
+org.apache.activemq.pool.
+org.apache.activemq.spring.
+org.apache.aries.transaction.
+org.apache.axis2.jaxws.spi.handler.
+org.apache.axis2.transport.jms.
+org.apache.bcel
+org.apache.carbondata.core.scan.expression.expressionresult
+org.apache.catalina.
+org.apache.cocoon.
+org.apache.commons.beanutils
+org.apache.commons.collections.comparators.
+org.apache.commons.collections.functors
+org.apache.commons.collections.functors.
+org.apache.commons.collections.transformer
+org.apache.commons.collections4.comparators
+org.apache.commons.collections4.functors
+org.apache.commons.collections4.transformer
+org.apache.commons.configuration
+org.apache.commons.dbcp
+org.apache.commons.fileupload
+org.apache.commons.jelly.
+org.apache.commons.logging.
+org.apache.commons.proxy.
+org.apache.cxf.jaxrs.provider.
+org.apache.hadoop.shaded.com.zaxxer.hikari.
+org.apache.http.auth.
+org.apache.http.conn.
+org.apache.http.cookie.
+org.apache.http.impl.
+org.apache.ibatis.datasource
+org.apache.ibatis.executor.
+org.apache.ibatis.javassist.
+org.apache.ibatis.ognl.
+org.apache.ibatis.parsing.
+org.apache.ibatis.reflection.
+org.apache.ibatis.scripting.
+org.apache.ignite.cache.jta.
+org.apache.log4j.
+org.apache.logging.
+org.apache.myfaces.context.servlet
+org.apache.openjpa.ee.
+org.apache.shiro.jndi.
+org.apache.shiro.realm.
+org.apache.tomcat
+org.apache.wicket.util
+org.apache.xalan
+org.apache.xbean.
+org.apache.xpath.xpathcontext
+org.codehaus.groovy.runtime
+org.codehaus.jackson.
+org.eclipse.jetty.
+org.geotools.filter.constantexpression
+org.h2.jdbcx.
+org.h2.server.
+org.hibernate
+org.javasimon.
+org.jaxen.
+org.jboss
+org.jdom.
+org.jdom2.transform.
+org.logicalcobwebs.
+org.mortbay.jetty.
+org.mozilla.javascript
+org.objectweb.asm.
+org.osjava.sj.
+org.python.core
+org.quartz.
+org.slf4j.
+org.springframework.
+org.yaml.snakeyaml.tokens.directivetoken
+sun.rmi.server.unicastref
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-api/pom.xml 
b/dubbo-config/dubbo-config-api/pom.xml
index 22e9d30..1881d81 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -31,6 +31,11 @@
     <dependencies>
         <dependency>
             <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
             <artifactId>dubbo-registry-api</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/GenericServiceTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/GenericServiceTest.java
index 9981cb1..54f0c2c 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/GenericServiceTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/GenericServiceTest.java
@@ -31,6 +31,7 @@ import com.alibaba.dubbo.rpc.service.GenericException;
 import com.alibaba.dubbo.rpc.service.GenericService;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
 import java.io.ByteArrayInputStream;
@@ -46,6 +47,11 @@ import java.util.concurrent.atomic.AtomicReference;
  */
 public class GenericServiceTest {
 
+    @Before
+    public void setup() {
+        System.setProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, 
"true");
+    }
+
     @Test
     public void testGenericServiceException() {
         ServiceConfig<GenericService> service = new 
ServiceConfig<GenericService>();
diff --git 
a/dubbo-registry/dubbo-registry-default/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
 
b/dubbo-registry/dubbo-registry-default/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
new file mode 100644
index 0000000..a7f6ddc
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-default/src/test/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory
@@ -0,0 +1 @@
+script=com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
index b8d9d87..1d82c9f 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
@@ -24,6 +24,8 @@ import com.alibaba.dubbo.common.extension.Activate;
 import com.alibaba.dubbo.common.extension.ExtensionLoader;
 import com.alibaba.dubbo.common.io.UnsafeByteArrayInputStream;
 import com.alibaba.dubbo.common.io.UnsafeByteArrayOutputStream;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
 import com.alibaba.dubbo.common.serialize.Serialization;
 import com.alibaba.dubbo.common.utils.PojoUtils;
 import com.alibaba.dubbo.common.utils.ReflectUtils;
@@ -48,6 +50,7 @@ import java.lang.reflect.Method;
  */
 @Activate(group = Constants.PROVIDER, order = -20000)
 public class GenericFilter implements Filter {
+    private static final Logger logger = 
LoggerFactory.getLogger(GenericFilter.class);
 
     @Override
     public Result invoke(Invoker<?> invoker, Invocation inv) throws 
RpcException {
@@ -74,6 +77,17 @@ public class GenericFilter implements Filter {
                         || 
ProtocolUtils.isDefaultGenericSerialization(generic)) {
                     args = PojoUtils.realize(args, params, 
method.getGenericParameterTypes());
                 } else if (ProtocolUtils.isJavaGenericSerialization(generic)) {
+                    if (!nativeJavaSerializerEnabled()) {
+                        String notice = "Trigger the safety barrier! " +
+                                "Native Java Serializer is not allowed by 
default." +
+                                "This means currently maybe being attacking by 
others. " +
+                                "If you are sure this is a mistake, " +
+                                "please set `" + 
Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE + "` enable in configuration! " +
+                                "Before doing so, please make sure you have 
configure JEP290 to prevent serialization attack.";
+                        logger.error(notice);
+                        throw new RpcException(new 
IllegalStateException(notice));
+                    }
+
                     for (int i = 0; i < args.length; i++) {
                         if (byte[].class == args[i].getClass()) {
                             try {
@@ -141,4 +155,9 @@ public class GenericFilter implements Filter {
         return invoker.invoke(inv);
     }
 
+    private boolean nativeJavaSerializerEnabled() {
+        return 
Boolean.parseBoolean(System.getProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE))
+                || 
Boolean.parseBoolean(System.getenv(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE))
+                || 
Boolean.parseBoolean(System.getenv(StringUtils.toOSStyleKey(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE)));
+    }
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
 
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
index 42bbd76..f10d44b 100644
--- 
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
+++ 
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
@@ -27,6 +27,7 @@ import com.alibaba.dubbo.rpc.Exporter;
 import com.alibaba.dubbo.rpc.ProxyFactory;
 import com.alibaba.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
 import junit.framework.Assert;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
@@ -52,7 +53,12 @@ public class DubboInvokerAvilableTest {
 
     @Before
     public void setUp() throws Exception {
-        protocol = new DubboProtocol();
+        protocol = DubboProtocol.getDubboProtocol();
+    }
+
+    @After
+    public void tearDown() {
+        protocol.destroy();
     }
 
     @Test
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
index bae0333..167f0a4 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
@@ -16,6 +16,7 @@
  */
 package com.alibaba.dubbo.rpc.protocol.hessian;
 
+import com.alibaba.dubbo.common.Constants;
 import com.alibaba.dubbo.common.URL;
 import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
 import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
@@ -34,6 +35,7 @@ import 
com.alibaba.dubbo.rpc.protocol.hessian.HessianServiceImpl.MyException;
 
 import com.alibaba.dubbo.rpc.service.GenericService;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
 import java.io.ByteArrayInputStream;
@@ -47,6 +49,11 @@ import static org.junit.Assert.fail;
  */
 public class HessianProtocolTest {
 
+    @Before
+    public void setup() {
+        System.setProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, 
"true");
+    }
+
     @Test
     public void testHessianProtocol() {
         HessianServiceImpl server = new HessianServiceImpl();
@@ -83,6 +90,8 @@ public class HessianProtocolTest {
 
     @Test
     public void testGenericInvokeWithNativeJava() throws IOException, 
ClassNotFoundException {
+        // temporary enable native java generic serialize
+        System.setProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, 
"true");
         HessianServiceImpl server = new HessianServiceImpl();
         Assert.assertFalse(server.isCalled());
         ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
@@ -106,6 +115,7 @@ public class HessianProtocolTest {
         Assert.assertEquals("Hello, haha", objectInput.readObject());
         invoker.destroy();
         exporter.unexport();
+        System.clearProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE);
     }
 
     @Test
diff --git 
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
index 014eed6..e05fb9e 100644
--- 
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
@@ -16,6 +16,7 @@
  */
 package com.alibaba.dubbo.rpc.protocol.http;
 
+import com.alibaba.dubbo.common.Constants;
 import com.alibaba.dubbo.common.URL;
 import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
 import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
@@ -27,6 +28,7 @@ import 
com.alibaba.dubbo.common.serialize.nativejava.NativeJavaSerialization;
 import com.alibaba.dubbo.rpc.*;
 import com.alibaba.dubbo.rpc.service.GenericService;
 import junit.framework.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
 import java.io.ByteArrayInputStream;
@@ -40,6 +42,11 @@ import static org.junit.Assert.fail;
  */
 public class HttpProtocolTest {
 
+    @Before
+    public void setup() {
+        System.setProperty(Constants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, 
"true");
+    }
+
     @Test
     public void testHttpProtocol() {
         HttpServiceImpl server = new HttpServiceImpl();

Reply via email to