mirror of
https://github.com/apache/dubbo.git
synced 2024-10-23 07:04:37 +08:00
Add serialization check (#11217)
This commit is contained in:
parent
671c7ff950
commit
84c1c35aae
@ -22,6 +22,7 @@ import org.apache.dubbo.common.convert.ConverterUtil;
|
||||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
|
||||
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.SerializeSecurityManager;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
@ -33,6 +34,7 @@ public class CommonScopeModelInitializer implements ScopeModelInitializer {
|
||||
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
|
||||
beanFactory.registerBean(FrameworkExecutorRepository.class);
|
||||
beanFactory.registerBean(ConverterUtil.class);
|
||||
beanFactory.registerBean(SerializeSecurityManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -429,6 +429,8 @@ public interface CommonConstants {
|
||||
|
||||
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";
|
||||
|
||||
String SERIALIZE_ALLOW_LIST_FILE_PATH = "security/serialize.allowlist";
|
||||
|
||||
String QOS_LIVE_PROBE_EXTENSION = "dubbo.application.liveness-probe";
|
||||
|
||||
String QOS_READY_PROBE_EXTENSION = "dubbo.application.readiness-probe";
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.utils;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AllowClassNotifyListener {
|
||||
|
||||
SerializeCheckStatus DEFAULT_STATUS = SerializeCheckStatus.STRICT;
|
||||
|
||||
void notify(SerializeCheckStatus status, Set<String> prefixList);
|
||||
}
|
@ -24,11 +24,11 @@ import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -46,7 +46,7 @@ public class ClassLoaderResourceLoader {
|
||||
GlobalResourcesRepository.registerGlobalDisposable(() -> destroy());
|
||||
}
|
||||
|
||||
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, List<ClassLoader> classLoaders) throws InterruptedException {
|
||||
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, Collection<ClassLoader> classLoaders) throws InterruptedException {
|
||||
Map<ClassLoader, Set<URL>> resources = new ConcurrentHashMap<>();
|
||||
CountDownLatch countDownLatch = new CountDownLatch(classLoaders.size());
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.utils;
|
||||
|
||||
public enum SerializeCheckStatus {
|
||||
DISABLED,
|
||||
WARN,
|
||||
STRICT,
|
||||
}
|
@ -17,7 +17,6 @@
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
@ -52,10 +51,10 @@ public class SerializeClassChecker {
|
||||
private final AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
private SerializeClassChecker() {
|
||||
String openCheckClass = ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
|
||||
String openCheckClass = System.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
|
||||
OPEN_CHECK_CLASS = Boolean.parseBoolean(openCheckClass);
|
||||
|
||||
String blockAllClassExceptAllow = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
|
||||
String blockAllClassExceptAllow = System.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
|
||||
|
||||
BLOCK_ALL_CLASS_EXCEPT_ALLOW = Boolean.parseBoolean(blockAllClassExceptAllow);
|
||||
|
||||
@ -79,8 +78,8 @@ public class SerializeClassChecker {
|
||||
logger.error(COMMON_IO_EXCEPTION, "", "", "Failed to load blocked class list! Will ignore default blocked list.", e);
|
||||
}
|
||||
|
||||
String allowedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
|
||||
String blockedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
|
||||
String allowedClassList = System.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
|
||||
String blockedClassList = System.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
|
||||
|
||||
if (StringUtils.isNotEmpty(allowedClassList)) {
|
||||
String[] classStrings = allowedClassList.trim().split(",");
|
||||
@ -120,34 +119,45 @@ public class SerializeClassChecker {
|
||||
* @throws IllegalArgumentException if class is blocked
|
||||
*/
|
||||
public void validateClass(String name) {
|
||||
validateClass(name, true);
|
||||
}
|
||||
|
||||
public boolean validateClass(String name, boolean failOnError) {
|
||||
if (!OPEN_CHECK_CLASS) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
if (CACHE == CLASS_ALLOW_LFU_CACHE.get(name)) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CACHE == CLASS_BLOCK_LFU_CACHE.get(name)) {
|
||||
error(name);
|
||||
if (failOnError) {
|
||||
error(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String allowedPrefix : CLASS_DESERIALIZE_ALLOWED_SET) {
|
||||
if (name.startsWith(allowedPrefix)) {
|
||||
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (failOnError) {
|
||||
error(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void error(String name) {
|
||||
|
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SERIALIZE_ALLOW_LIST_FILE_PATH;
|
||||
|
||||
public class SerializeSecurityManager {
|
||||
private final Set<String> allowedPrefix = new LinkedHashSet<>();
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(SerializeSecurityManager.class);
|
||||
|
||||
private final SerializeClassChecker checker = SerializeClassChecker.getInstance();
|
||||
|
||||
private final Set<AllowClassNotifyListener> listeners = new ConcurrentHashSet<>();
|
||||
|
||||
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
|
||||
|
||||
public SerializeSecurityManager(FrameworkModel frameworkModel) {
|
||||
try {
|
||||
Set<ClassLoader> classLoaders = frameworkModel.getClassLoaders();
|
||||
List<URL> urls = ClassLoaderResourceLoader.loadResources(SERIALIZE_ALLOW_LIST_FILE_PATH, classLoaders)
|
||||
.values()
|
||||
.stream()
|
||||
.flatMap(Set::stream)
|
||||
.collect(Collectors.toList());
|
||||
for (URL u : urls) {
|
||||
try {
|
||||
String[] lines = IOUtils.readLines(u.openStream());
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (StringUtils.isEmpty(line) || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
allowedPrefix.add(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load allow class list! Will ignore allow lis from " + u, e);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Failed to load allow class list! Will ignore allow list from configuration.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerInterface(Class<?> clazz) {
|
||||
Set<Class<?>> markedClass = new HashSet<>();
|
||||
markedClass.add(clazz);
|
||||
|
||||
addToAllow(clazz.getName());
|
||||
|
||||
Method[] methodsToExport = clazz.getMethods();
|
||||
|
||||
for (Method method : methodsToExport) {
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
for (Class<?> parameterType : parameterTypes) {
|
||||
checkClass(markedClass, parameterType);
|
||||
}
|
||||
|
||||
Type[] genericParameterTypes = method.getGenericParameterTypes();
|
||||
for (Type genericParameterType : genericParameterTypes) {
|
||||
checkType(markedClass, genericParameterType);
|
||||
}
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
checkClass(markedClass, returnType);
|
||||
|
||||
Type genericReturnType = method.getGenericReturnType();
|
||||
checkType(markedClass, genericReturnType);
|
||||
|
||||
Class<?>[] exceptionTypes = method.getExceptionTypes();
|
||||
for (Class<?> exceptionType : exceptionTypes) {
|
||||
checkClass(markedClass, exceptionType);
|
||||
}
|
||||
|
||||
Type[] genericExceptionTypes = method.getGenericExceptionTypes();
|
||||
for (Type genericExceptionType : genericExceptionTypes) {
|
||||
checkType(markedClass, genericExceptionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkType(Set<Class<?>> markedClass, Type type) {
|
||||
if (type instanceof Class) {
|
||||
checkClass(markedClass, (Class<?>) type);
|
||||
} else if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
checkClass(markedClass, (Class<?>) parameterizedType.getRawType());
|
||||
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
|
||||
checkType(markedClass, actualTypeArgument);
|
||||
}
|
||||
} else if (type instanceof GenericArrayType) {
|
||||
GenericArrayType genericArrayType = (GenericArrayType) type;
|
||||
checkType(markedClass, genericArrayType.getGenericComponentType());
|
||||
} else if (type instanceof TypeVariable) {
|
||||
TypeVariable typeVariable = (TypeVariable) type;
|
||||
for (Type bound : typeVariable.getBounds()) {
|
||||
checkType(markedClass, bound);
|
||||
}
|
||||
} else if (type instanceof WildcardType) {
|
||||
WildcardType wildcardType = (WildcardType) type;
|
||||
for (Type bound : wildcardType.getUpperBounds()) {
|
||||
checkType(markedClass, bound);
|
||||
}
|
||||
for (Type bound : wildcardType.getLowerBounds()) {
|
||||
checkType(markedClass, bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkClass(Set<Class<?>> markedClass, Class<?> clazz) {
|
||||
if (markedClass.contains(clazz)) {
|
||||
return;
|
||||
}
|
||||
|
||||
markedClass.add(clazz);
|
||||
|
||||
addToAllow(clazz.getName());
|
||||
|
||||
Class<?>[] interfaces = clazz.getInterfaces();
|
||||
for (Class<?> interfaceClass : interfaces) {
|
||||
checkClass(markedClass, interfaceClass);
|
||||
}
|
||||
|
||||
Class<?> superclass = clazz.getSuperclass();
|
||||
if (superclass != null) {
|
||||
checkClass(markedClass, superclass);
|
||||
}
|
||||
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
if (Modifier.isTransient(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?> fieldClass = field.getType();
|
||||
checkClass(markedClass, fieldClass);
|
||||
checkType(markedClass, field.getGenericType());
|
||||
}
|
||||
}
|
||||
|
||||
protected void addToAllow(String className) {
|
||||
if (!checker.validateClass(className, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean modified;
|
||||
|
||||
// ignore jdk
|
||||
if (className.startsWith("java.") || className.startsWith("javax.") || className.startsWith("com.sun.") ||
|
||||
className.startsWith("sun.") || className.startsWith("jdk.")) {
|
||||
modified = allowedPrefix.add(className);
|
||||
if (modified) {
|
||||
notifyListeners();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// add group package
|
||||
String[] subs = className.split("\\.");
|
||||
if (subs.length > 3) {
|
||||
modified = allowedPrefix.add(subs[0] + "." + subs[1] + "." + subs[2]);
|
||||
} else {
|
||||
modified = allowedPrefix.add(className);
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListener(AllowClassNotifyListener listener) {
|
||||
listeners.add(listener);
|
||||
listener.notify(checkStatus, allowedPrefix);
|
||||
}
|
||||
|
||||
private void notifyListeners() {
|
||||
for (AllowClassNotifyListener listener : listeners) {
|
||||
listener.notify(checkStatus, allowedPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<String> getAllowedPrefix() {
|
||||
return allowedPrefix;
|
||||
}
|
||||
}
|
125
dubbo-common/src/main/resources/security/serialize.allowlist
Normal file
125
dubbo-common/src/main/resources/security/serialize.allowlist
Normal file
@ -0,0 +1,125 @@
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
boolean
|
||||
byte
|
||||
char
|
||||
double
|
||||
float
|
||||
int
|
||||
long
|
||||
short
|
||||
java.lang.AutoCloseable
|
||||
java.lang.Boolean
|
||||
java.lang.Byte
|
||||
java.lang.Character
|
||||
java.lang.Class
|
||||
java.lang.Cloneable
|
||||
java.lang.Double
|
||||
java.lang.Exception
|
||||
java.lang.Float
|
||||
java.lang.IllegalAccessError
|
||||
java.lang.IllegalAccessException
|
||||
java.lang.IllegalArgumentException
|
||||
java.lang.IllegalMonitorStateException
|
||||
java.lang.IllegalStateException
|
||||
java.lang.IllegalThreadStateException
|
||||
java.lang.IndexOutOfBoundsException
|
||||
java.lang.InstantiationError
|
||||
java.lang.InstantiationException
|
||||
java.lang.Integer
|
||||
java.lang.InternalError
|
||||
java.lang.InterruptedException
|
||||
java.lang.LinkageError
|
||||
java.lang.Long
|
||||
java.lang.NegativeArraySizeException
|
||||
java.lang.NoClassDefFoundError
|
||||
java.lang.NoSuchFieldError
|
||||
java.lang.NoSuchFieldException
|
||||
java.lang.NoSuchMethodError
|
||||
java.lang.NoSuchMethodException
|
||||
java.lang.NullPointerException
|
||||
java.lang.Number
|
||||
java.lang.NumberFormatException
|
||||
java.lang.Object
|
||||
java.lang.OutOfMemoryError
|
||||
java.lang.RuntimeException
|
||||
java.lang.SecurityException
|
||||
java.lang.Short
|
||||
java.lang.StackOverflowError
|
||||
java.lang.StackTraceElement
|
||||
java.lang.String
|
||||
java.lang.StringIndexOutOfBoundsException
|
||||
java.lang.TypeNotPresentException
|
||||
java.lang.VerifyError
|
||||
java.math.BigDecimal
|
||||
java.math.BigInteger
|
||||
java.text.SimpleDateFormat
|
||||
java.time.format.DateTimeFormatter
|
||||
java.time.Instant
|
||||
java.time.LocalDate
|
||||
java.time.LocalDateTime
|
||||
java.time.LocalTime
|
||||
java.util.ArrayList
|
||||
java.util.Arrays$ArrayList
|
||||
java.util.BitSet
|
||||
java.util.Calendar
|
||||
java.util.Collections$EmptyList
|
||||
java.util.Collections$EmptyMap
|
||||
java.util.Collections$SingletonSet
|
||||
java.util.Collections$UnmodifiableCollection
|
||||
java.util.Collections$UnmodifiableList
|
||||
java.util.Collections$UnmodifiableMap
|
||||
java.util.Collections$UnmodifiableNavigableMap
|
||||
java.util.Collections$UnmodifiableNavigableSet
|
||||
java.util.Collections$UnmodifiableRandomAccessList
|
||||
java.util.Collections$UnmodifiableSet
|
||||
java.util.Collections$UnmodifiableSortedMap
|
||||
java.util.Collections$UnmodifiableSortedSet
|
||||
java.util.concurrent.atomic.AtomicBoolean
|
||||
java.util.concurrent.atomic.AtomicInteger
|
||||
java.util.concurrent.atomic.AtomicIntegerArray
|
||||
java.util.concurrent.atomic.AtomicLong
|
||||
java.util.concurrent.atomic.AtomicLongArray
|
||||
java.util.concurrent.atomic.AtomicReference
|
||||
java.util.concurrent.ConcurrentHashMap
|
||||
java.util.concurrent.ConcurrentLinkedQueue
|
||||
java.util.concurrent.ConcurrentMap
|
||||
java.util.concurrent.ConcurrentSkipListMap
|
||||
java.util.concurrent.ConcurrentSkipListSet
|
||||
java.util.concurrent.CopyOnWriteArrayList
|
||||
java.util.concurrent.TimeUnit
|
||||
java.util.Currency
|
||||
java.util.Date
|
||||
java.util.EnumSet
|
||||
java.util.HashMap
|
||||
java.util.HashSet
|
||||
java.util.Hashtable
|
||||
java.util.IdentityHashMap
|
||||
java.util.LinkedHashMap
|
||||
java.util.LinkedHashSet
|
||||
java.util.LinkedList
|
||||
java.util.List
|
||||
java.util.Locale
|
||||
java.util.Map
|
||||
java.util.Set
|
||||
java.util.TreeMap
|
||||
java.util.TreeSet
|
||||
java.util.UUID
|
||||
java.util.WeakHashMap
|
||||
org.apache.dubbo
|
@ -18,33 +18,38 @@
|
||||
#
|
||||
aj.org.objectweb.asm.
|
||||
br.com.anteros.
|
||||
bsh.
|
||||
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
|
||||
clojure.
|
||||
com.alibaba.citrus.springext.support.parser.
|
||||
com.alibaba.citrus.springext.util.SpringExtUtil.
|
||||
com.alibaba.druid.pool.
|
||||
com.alibaba.druid.stat.jdbcdatasourcestat
|
||||
com.alibaba.fastjson.annotation
|
||||
com.alipay.custrelation.service.model.redress.pair
|
||||
com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
|
||||
com.alipay.custrelation.service.model.redress.
|
||||
com.alipay.oceanbase.obproxy.druid.pool.
|
||||
com.caucho.
|
||||
com.ibatis.
|
||||
com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
|
||||
com.ibm.xltxe.rnm1.xtq.bcel.util.
|
||||
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.mysql.jdbc.util.
|
||||
com.p6spy.engine.
|
||||
com.rometools.rome.feed.impl.equalsbean
|
||||
com.rometools.rome.feed.impl.tostringbean
|
||||
com.rometools.rome.feed.
|
||||
com.sun.
|
||||
com.taobao.eagleeye.wrapper
|
||||
com.taobao.vipserver.commons.collections.functors.
|
||||
com.zaxxer.hikari.
|
||||
flex.messaging.util.concurrent.
|
||||
java.awt.i
|
||||
java.awt.p
|
||||
java.beans.expression
|
||||
groovy.lang.
|
||||
java.awt.
|
||||
java.beans.
|
||||
java.io.closeable
|
||||
java.io.serializable
|
||||
java.lang.autocloseable
|
||||
@ -52,41 +57,46 @@ java.lang.class
|
||||
java.lang.cloneable
|
||||
java.lang.iterable
|
||||
java.lang.object
|
||||
java.lang.ProcessBuilder
|
||||
java.lang.readable
|
||||
java.lang.runnable
|
||||
java.lang.Runtime
|
||||
java.lang.thread
|
||||
java.lang.unixprocess
|
||||
java.net.inetaddress
|
||||
java.net.socket
|
||||
java.net.url
|
||||
java.rmi
|
||||
java.security.signedobject
|
||||
java.security.
|
||||
java.util.collection
|
||||
java.util.eventlistener
|
||||
java.util.jar.
|
||||
java.util.logging.
|
||||
java.util.prefs.
|
||||
java.util.ServiceLoader
|
||||
java.util.serviceloader$lazyiterator
|
||||
java.util.StringTokenizer
|
||||
javassist.
|
||||
javax.activation.
|
||||
javax.imageio.imageio$containsfilter
|
||||
javax.imageio.spi.serviceregistry
|
||||
javax.imageio.
|
||||
javax.management.
|
||||
javax.media.jai.remote.
|
||||
javax.naming.
|
||||
javax.net.
|
||||
javax.print.
|
||||
javax.script.
|
||||
javax.sound.
|
||||
javax.swing.j
|
||||
javax.swing.
|
||||
javax.tools.
|
||||
javax.xml
|
||||
jdk.internal.
|
||||
jodd.db.connection.
|
||||
junit.
|
||||
net.bytebuddy.dynamic.loading.bytearrayclassloader
|
||||
net.bytebuddy.dynamic.loading.
|
||||
net.sf.cglib.
|
||||
net.sf.ehcache.hibernate.
|
||||
net.sf.ehcache.transaction.manager.
|
||||
ognl.
|
||||
oracle.jdbc.
|
||||
oracle.jms.aq
|
||||
oracle.net
|
||||
@ -100,10 +110,12 @@ org.apache.aries.transaction.
|
||||
org.apache.axis2.jaxws.spi.handler.
|
||||
org.apache.axis2.transport.jms.
|
||||
org.apache.bcel
|
||||
org.apache.carbondata.core.scan.expression.
|
||||
org.apache.carbondata.core.scan.expression.expressionresult
|
||||
org.apache.catalina.
|
||||
org.apache.cocoon.
|
||||
org.apache.commons.beanutils
|
||||
org.apache.commons.codec.
|
||||
org.apache.commons.collections.comparators.
|
||||
org.apache.commons.collections.functors
|
||||
org.apache.commons.collections.functors.
|
||||
@ -112,6 +124,7 @@ org.apache.commons.collections4.comparators
|
||||
org.apache.commons.collections4.functors
|
||||
org.apache.commons.collections4.transformer
|
||||
org.apache.commons.configuration
|
||||
org.apache.commons.configuration2.
|
||||
org.apache.commons.dbcp
|
||||
org.apache.commons.fileupload
|
||||
org.apache.commons.jelly.
|
||||
@ -130,32 +143,43 @@ org.apache.ibatis.ognl.
|
||||
org.apache.ibatis.parsing.
|
||||
org.apache.ibatis.reflection.
|
||||
org.apache.ibatis.scripting.
|
||||
org.apache.ignite.cache.
|
||||
org.apache.ignite.cache.jta.
|
||||
org.apache.log.output.db.
|
||||
org.apache.log4j.
|
||||
org.apache.logging.
|
||||
org.apache.myfaces.context.servlet
|
||||
org.apache.myfaces.view.facelets.el.
|
||||
org.apache.openjpa.ee.
|
||||
org.apache.shiro.jndi.
|
||||
org.apache.shiro.realm.
|
||||
org.apache.shiro.
|
||||
org.apache.tomcat
|
||||
org.apache.velocity.
|
||||
org.apache.wicket.util
|
||||
org.apache.xalan
|
||||
org.apache.xbean.
|
||||
org.apache.xpath.xpathcontext
|
||||
org.apache.xpath.
|
||||
org.apache.zookeeper.
|
||||
org.aspectj.
|
||||
org.codehaus.groovy.runtime
|
||||
org.codehaus.jackson.
|
||||
org.datanucleus.store.rdbms.datasource.dbcp.datasources.
|
||||
org.dom4j.
|
||||
org.eclipse.jetty.
|
||||
org.geotools.filter.constantexpression
|
||||
org.geotools.filter.
|
||||
org.h2.jdbcx.
|
||||
org.h2.server.
|
||||
org.h2.value.
|
||||
org.hibernate
|
||||
org.javasimon.
|
||||
org.jaxen.
|
||||
org.jboss
|
||||
org.jdom.
|
||||
org.jdom2.transform.
|
||||
org.junit.
|
||||
org.logicalcobwebs.
|
||||
org.mockito.
|
||||
org.mortbay.jetty.
|
||||
org.mortbay.log.
|
||||
org.mozilla.javascript
|
||||
org.objectweb.asm.
|
||||
org.osjava.sj.
|
||||
@ -163,5 +187,11 @@ org.python.core
|
||||
org.quartz.
|
||||
org.slf4j.
|
||||
org.springframework.
|
||||
org.yaml.snakeyaml.tokens.directivetoken
|
||||
sun.rmi.server.unicastref
|
||||
org.thymeleaf.
|
||||
org.yaml.snakeyaml.tokens.
|
||||
pstore.shaded.org.apache.commons.collections.
|
||||
sun.print.
|
||||
sun.rmi.server.
|
||||
sun.rmi.transport.
|
||||
weblogic.ejb20.internal.
|
||||
weblogic.jms.common.
|
||||
|
29
dubbo-common/src/test/java/com/pojo/Demo1.java
Normal file
29
dubbo-common/src/test/java/com/pojo/Demo1.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo1 {
|
||||
private Simple simple;
|
||||
|
||||
public Simple getSimple() {
|
||||
return simple;
|
||||
}
|
||||
|
||||
public void setSimple(Simple simple) {
|
||||
this.simple = simple;
|
||||
}
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo2.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo2.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo2 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo3.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo3.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo3 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo4.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo4.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo4 extends Demo3 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo5.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo5.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo5 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo6.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo6.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo6 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo7.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo7.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo7 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Demo8.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Demo8.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Demo8 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/DemoException1.java
Normal file
20
dubbo-common/src/test/java/com/pojo/DemoException1.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class DemoException1 extends Exception{
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/DemoException2.java
Normal file
20
dubbo-common/src/test/java/com/pojo/DemoException2.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class DemoException2 extends Exception {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/DemoException3.java
Normal file
20
dubbo-common/src/test/java/com/pojo/DemoException3.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class DemoException3 extends DemoException2 {
|
||||
}
|
20
dubbo-common/src/test/java/com/pojo/Simple.java
Normal file
20
dubbo-common/src/test/java/com/pojo/Simple.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.pojo;
|
||||
|
||||
public class Simple {
|
||||
}
|
52
dubbo-common/src/test/java/com/service/DemoService1.java
Normal file
52
dubbo-common/src/test/java/com/service/DemoService1.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.service;
|
||||
|
||||
import com.pojo.Demo1;
|
||||
import com.pojo.Demo2;
|
||||
import com.pojo.Demo4;
|
||||
import com.pojo.Demo5;
|
||||
import com.pojo.Demo6;
|
||||
import com.pojo.Demo7;
|
||||
import com.pojo.Demo8;
|
||||
import com.pojo.DemoException1;
|
||||
import com.pojo.DemoException3;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
public interface DemoService1<T extends Demo8> {
|
||||
Demo1 getDemo1();
|
||||
|
||||
void setDemo2(Demo2 demo2);
|
||||
|
||||
List<Demo4> getDemo4s();
|
||||
|
||||
List<HashSet<LinkedList<Set<Vector<Map<? extends Demo5, ? super Demo6>>>>>> getDemo5s();
|
||||
|
||||
List<Demo7>[] getDemo7s();
|
||||
|
||||
List<T> getTs();
|
||||
|
||||
void echo1() throws DemoException1;
|
||||
|
||||
void echo2() throws DemoException3;
|
||||
}
|
20
dubbo-common/src/test/java/com/service/DemoService2.java
Normal file
20
dubbo-common/src/test/java/com/service/DemoService2.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.service;
|
||||
|
||||
public interface DemoService2 extends DemoService1 {
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.service.DemoService1;
|
||||
import com.service.DemoService2;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
public class SerializeSecurityManagerTest {
|
||||
@Test
|
||||
public void test() {
|
||||
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
|
||||
ssm.registerListener(new TestAllowClassNotifyListener());
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.HashMap"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.DemoInterface"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.sun.Interface1"));
|
||||
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
|
||||
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addToAllow() {
|
||||
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
|
||||
ssm.registerListener(new TestAllowClassNotifyListener());
|
||||
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
|
||||
ssm.addToAllow("com.sun.Interface2");
|
||||
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
|
||||
ssm.addToAllow("java.util.Interface1");
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.Interface1"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
|
||||
ssm.addToAllow("java.util.package.Interface1");
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.package.Interface1"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
|
||||
ssm.addToAllow("com.example.Interface2");
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.Interface2"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
|
||||
ssm.addToAllow("com.example.package.Interface1");
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.package"));
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegister1() {
|
||||
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
|
||||
ssm.registerListener(new TestAllowClassNotifyListener());
|
||||
|
||||
ssm.registerInterface(DemoService1.class);
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService1"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
|
||||
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
|
||||
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRegister2() {
|
||||
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
|
||||
ssm.registerListener(new TestAllowClassNotifyListener());
|
||||
|
||||
ssm.registerInterface(DemoService2.class);
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService2"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
|
||||
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
|
||||
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
|
||||
|
||||
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.utils;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class TestAllowClassNotifyListener implements AllowClassNotifyListener {
|
||||
private final static AtomicReference<Set<String>> prefixList = new AtomicReference<>();
|
||||
|
||||
@Override
|
||||
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
|
||||
TestAllowClassNotifyListener.prefixList.set(prefixList);
|
||||
}
|
||||
|
||||
public static Set<String> getPrefixList() {
|
||||
return prefixList.get();
|
||||
}
|
||||
}
|
20
dubbo-common/src/test/resources/security/serialize.allowlist
Normal file
20
dubbo-common/src/test/resources/security/serialize.allowlist
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
com.example.DemoInterface
|
||||
com.sun.Interface1
|
@ -1038,6 +1038,7 @@ class ReferenceConfigTest {
|
||||
@Test
|
||||
@DisabledForJreRange(min = JRE.JAVA_16)
|
||||
public void testDifferentClassLoaderRequest() throws Exception {
|
||||
FrameworkModel frameworkModel = FrameworkModel.defaultModel();
|
||||
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
|
||||
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
@ -1046,7 +1047,7 @@ class ReferenceConfigTest {
|
||||
TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);
|
||||
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
|
||||
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
|
||||
ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
|
||||
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
|
||||
ModuleModel moduleModel = new ModuleModel(applicationModel);
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
demo.
|
@ -887,4 +887,5 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
@ -657,12 +657,6 @@
|
||||
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
|
@ -274,12 +274,6 @@
|
||||
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
|
||||
</resource>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
|
@ -1065,19 +1065,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer",
|
||||
"allPublicMethods": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "<init>",
|
||||
"parameterTypes": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer"
|
||||
},
|
||||
{
|
||||
"name": "org.apache.dubbo.common.status.reporter.FrameworkStatusReportService",
|
||||
"methods": [
|
||||
|
@ -28,9 +28,6 @@
|
||||
{
|
||||
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization\\E"
|
||||
},
|
||||
{
|
||||
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer\\E"
|
||||
},
|
||||
{
|
||||
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool\\E"
|
||||
},
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.rpc.protocol;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.utils.SerializeSecurityManager;
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.ProtocolServer;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
import org.apache.dubbo.rpc.model.ServiceDescriptor;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Activate(order = 200)
|
||||
public class ProtocolSecurityWrapper implements Protocol {
|
||||
private final Protocol protocol;
|
||||
|
||||
public ProtocolSecurityWrapper(Protocol protocol) {
|
||||
if (protocol == null) {
|
||||
throw new IllegalArgumentException("protocol == null");
|
||||
}
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultPort() {
|
||||
return protocol.getDefaultPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
|
||||
ServiceModel serviceModel = invoker.getUrl().getServiceModel();
|
||||
ScopeModel scopeModel = invoker.getUrl().getScopeModel();
|
||||
Optional.ofNullable(serviceModel)
|
||||
.map(ServiceModel::getServiceModel)
|
||||
.map(ServiceDescriptor::getServiceInterfaceClass)
|
||||
.ifPresent((interfaceClass) -> {
|
||||
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
|
||||
.getBeanFactory().getBean(SerializeSecurityManager.class);
|
||||
serializeSecurityManager.registerInterface(interfaceClass);
|
||||
});
|
||||
return protocol.export(invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
|
||||
ServiceModel serviceModel = url.getServiceModel();
|
||||
ScopeModel scopeModel = url.getScopeModel();
|
||||
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
|
||||
.getBeanFactory().getBean(SerializeSecurityManager.class);
|
||||
|
||||
Optional.ofNullable(serviceModel)
|
||||
.map(ServiceModel::getServiceModel)
|
||||
.map(ServiceDescriptor::getServiceInterfaceClass)
|
||||
.ifPresent(serializeSecurityManager::registerInterface);
|
||||
serializeSecurityManager.registerInterface(type);
|
||||
|
||||
return protocol.refer(type, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
protocol.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProtocolServer> getServers() {
|
||||
return protocol.getServers();
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
|
||||
mock=org.apache.dubbo.rpc.support.MockProtocol
|
||||
serializationwrapper=org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper
|
||||
securitywrapper=org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper
|
||||
|
@ -32,11 +32,15 @@ public class FastJson2ObjectInput implements ObjectInput {
|
||||
|
||||
private final Fastjson2CreatorManager fastjson2CreatorManager;
|
||||
|
||||
private final Fastjson2SecurityManager fastjson2SecurityManager;
|
||||
|
||||
private volatile ClassLoader classLoader;
|
||||
private final InputStream is;
|
||||
|
||||
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager, InputStream in) {
|
||||
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager,
|
||||
Fastjson2SecurityManager fastjson2SecurityManager, InputStream in) {
|
||||
this.fastjson2CreatorManager = fastjson2CreatorManager;
|
||||
this.fastjson2SecurityManager = fastjson2SecurityManager;
|
||||
this.classLoader = Thread.currentThread().getContextClassLoader();
|
||||
this.is = in;
|
||||
fastjson2CreatorManager.setCreator(classLoader);
|
||||
@ -107,8 +111,9 @@ public class FastJson2ObjectInput implements ObjectInput {
|
||||
if (read != length) {
|
||||
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
|
||||
}
|
||||
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
|
||||
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
|
||||
JSONReader.Feature.UseDefaultConstructorAsPossible,
|
||||
JSONReader.Feature.ErrorOnNoneSerializable,
|
||||
JSONReader.Feature.UseNativeObject,
|
||||
JSONReader.Feature.FieldBased);
|
||||
}
|
||||
@ -123,8 +128,9 @@ public class FastJson2ObjectInput implements ObjectInput {
|
||||
if (read != length) {
|
||||
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
|
||||
}
|
||||
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
|
||||
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
|
||||
JSONReader.Feature.UseDefaultConstructorAsPossible,
|
||||
JSONReader.Feature.ErrorOnNoneSerializable,
|
||||
JSONReader.Feature.UseNativeObject,
|
||||
JSONReader.Feature.FieldBased);
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ public class FastJson2ObjectOutput implements ObjectOutput {
|
||||
updateClassLoaderIfNeed();
|
||||
byte[] bytes = JSONB.toBytes(obj, JSONWriter.Feature.WriteClassName,
|
||||
JSONWriter.Feature.FieldBased,
|
||||
JSONWriter.Feature.ErrorOnNoneSerializable,
|
||||
JSONWriter.Feature.ReferenceDetection,
|
||||
JSONWriter.Feature.WriteNulls,
|
||||
JSONWriter.Feature.NotWriteDefaultValue,
|
||||
|
@ -39,8 +39,11 @@ public class FastJson2Serialization implements Serialization {
|
||||
|
||||
private final Fastjson2CreatorManager fastjson2CreatorManager;
|
||||
|
||||
private final Fastjson2SecurityManager fastjson2SecurityManager;
|
||||
|
||||
public FastJson2Serialization(FrameworkModel frameworkModel) {
|
||||
this.fastjson2CreatorManager = frameworkModel.getBeanFactory().getBean(Fastjson2CreatorManager.class);
|
||||
this.fastjson2SecurityManager = frameworkModel.getBeanFactory().getBean(Fastjson2SecurityManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -60,7 +63,7 @@ public class FastJson2Serialization implements Serialization {
|
||||
|
||||
@Override
|
||||
public ObjectInput deserialize(URL url, InputStream input) throws IOException {
|
||||
return new FastJson2ObjectInput(fastjson2CreatorManager, input);
|
||||
return new FastJson2ObjectInput(fastjson2CreatorManager, fastjson2SecurityManager, input);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,10 +23,12 @@ import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
|
||||
public class Fastjson2ScopeModelInitializer implements ScopeModelInitializer {
|
||||
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
|
||||
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
|
||||
beanFactory.registerBean(Fastjson2CreatorManager.class);
|
||||
beanFactory.registerBean(Fastjson2SecurityManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.fastjson2;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.SerializeCheckStatus;
|
||||
import org.apache.dubbo.common.utils.SerializeSecurityManager;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler;
|
||||
import com.alibaba.fastjson2.filter.Filter;
|
||||
import com.alibaba.fastjson2.util.TypeUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.alibaba.fastjson2.util.TypeUtils.loadClass;
|
||||
|
||||
public class Fastjson2SecurityManager implements AllowClassNotifyListener {
|
||||
private Filter securityFilter = new Handler(AllowClassNotifyListener.DEFAULT_STATUS, new String[0]);
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(Fastjson2SecurityManager.class);
|
||||
|
||||
private final static Set<String> warnedClasses = new ConcurrentHashSet<>(1);
|
||||
|
||||
public Fastjson2SecurityManager(FrameworkModel frameworkModel) {
|
||||
SerializeSecurityManager securityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
|
||||
securityManager.registerListener(this);
|
||||
}
|
||||
|
||||
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
|
||||
this.securityFilter = new Handler(status, prefixList.toArray(new String[0]));
|
||||
}
|
||||
|
||||
public Filter getSecurityFilter() {
|
||||
return securityFilter;
|
||||
}
|
||||
|
||||
public static class Handler extends ContextAutoTypeBeforeHandler {
|
||||
final SerializeCheckStatus status;
|
||||
final Map<String, Class<?>> classCache = new ConcurrentHashMap<>(16, 0.75f, 1);
|
||||
|
||||
public Handler(SerializeCheckStatus status, String[] acceptNames) {
|
||||
super(true, acceptNames);
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> apply(String typeName, Class<?> expectClass, long features) {
|
||||
switch (status) {
|
||||
case STRICT:
|
||||
return super.apply(typeName, expectClass, features);
|
||||
case WARN:
|
||||
Class<?> tryLoad = super.apply(typeName, expectClass, features);
|
||||
if (tryLoad != null) {
|
||||
return tryLoad;
|
||||
}
|
||||
case DISABLED:
|
||||
Class<?> localClass = loadClassDirectly(typeName);
|
||||
if (localClass != null) {
|
||||
if (status == SerializeCheckStatus.WARN && warnedClasses.add(typeName)) {
|
||||
logger.error("[Serialization Security] Serialized class " + localClass.getName() + " is not in allow list. " +
|
||||
"Current mode is `WARN`, will allow to deserialize it by default. " +
|
||||
"Dubbo will set to `STRICT` mode by default in the future. " +
|
||||
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
|
||||
}
|
||||
return localClass;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> loadClassDirectly(String typeName) {
|
||||
Class<?> clazz = classCache.get(typeName);
|
||||
|
||||
if (clazz == null) {
|
||||
clazz = TypeUtils.getMapping(typeName);
|
||||
}
|
||||
|
||||
if (clazz == null) {
|
||||
clazz = loadClass(typeName);
|
||||
}
|
||||
|
||||
if (clazz != null) {
|
||||
Class<?> origin = classCache.putIfAbsent(typeName, clazz);
|
||||
if (origin != null) {
|
||||
clazz = origin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.SerializeCheckStatus;
|
||||
import org.apache.dubbo.common.utils.SerializeSecurityManager;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Inspired by Fastjson2
|
||||
* see com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler#apply(java.lang.String, java.lang.Class, long)
|
||||
*/
|
||||
public class Hessian2AllowClassManager implements AllowClassNotifyListener {
|
||||
private static final long MAGIC_HASH_CODE = 0xcbf29ce484222325L;
|
||||
private static final long MAGIC_PRIME = 0x100000001b3L;
|
||||
private static final Logger logger = LoggerFactory.getLogger(Hessian2AllowClassManager.class);
|
||||
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
|
||||
private final static Set<String> warnedClasses = new ConcurrentHashSet<>(1);
|
||||
private volatile long[] allowPrefixes = new long[0];
|
||||
|
||||
public Hessian2AllowClassManager(FrameworkModel frameworkModel) {
|
||||
SerializeSecurityManager serializeSecurityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
|
||||
serializeSecurityManager.registerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
|
||||
this.checkStatus = status;
|
||||
long[] array = new long[prefixList.size()];
|
||||
|
||||
int index = 0;
|
||||
for (String name : prefixList) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long hashCode = MAGIC_HASH_CODE;
|
||||
for (int j = 0; j < name.length(); ++j) {
|
||||
char ch = name.charAt(j);
|
||||
if (ch == '$') {
|
||||
ch = '.';
|
||||
}
|
||||
hashCode ^= ch;
|
||||
hashCode *= MAGIC_PRIME;
|
||||
}
|
||||
|
||||
array[index++] = hashCode;
|
||||
}
|
||||
|
||||
if (index != array.length) {
|
||||
array = Arrays.copyOf(array, index);
|
||||
}
|
||||
Arrays.sort(array);
|
||||
this.allowPrefixes = array;
|
||||
}
|
||||
|
||||
public Class<?> loadClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
|
||||
if (checkStatus == SerializeCheckStatus.DISABLED) {
|
||||
return Class.forName(className, false, classLoader);
|
||||
}
|
||||
|
||||
long hash = MAGIC_HASH_CODE;
|
||||
for (int i = 0, typeNameLength = className.length(); i < typeNameLength; ++i) {
|
||||
char ch = className.charAt(i);
|
||||
if (ch == '$') {
|
||||
ch = '.';
|
||||
}
|
||||
hash ^= ch;
|
||||
hash *= MAGIC_PRIME;
|
||||
|
||||
if (Arrays.binarySearch(allowPrefixes, hash) >= 0) {
|
||||
return Class.forName(className, false, classLoader);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkStatus == SerializeCheckStatus.STRICT) {
|
||||
String msg = "[Serialization Security] Serialized class " + className + " is not in allow list. " +
|
||||
"Current mode is `STRICT`, will disallow to deserialize it by default. " +
|
||||
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
|
||||
if (warnedClasses.add(className)) {
|
||||
logger.error(msg);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(msg);
|
||||
} else {
|
||||
Class<?> clazz = Class.forName(className, false, classLoader);
|
||||
if (warnedClasses.add(className)) {
|
||||
logger.error("[Serialization Security] Serialized class " + clazz.getName() + " is not in allow list. " +
|
||||
"Current mode is `WARN`, will allow to deserialize it by default. " +
|
||||
"Dubbo will set to `STRICT` mode by default in the future. " +
|
||||
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
}
|
@ -14,18 +14,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.serialize.hessian2.dubbo;
|
||||
package org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeClassLoaderListener;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
public class DefaultHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
|
||||
public class Hessian2ClassLoaderListener implements ScopeClassLoaderListener<FrameworkModel> {
|
||||
@Override
|
||||
protected SerializerFactory createSerializerFactory() {
|
||||
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory();
|
||||
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
|
||||
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
|
||||
return hessian2SerializerFactory;
|
||||
public void onAddClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
|
||||
Hessian2FactoryManager hessian2FactoryManager = scopeModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
|
||||
hessian2FactoryManager.onRemoveClassLoader(classLoader);
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class Hessian2FactoryManager {
|
||||
String WHITELIST = "dubbo.application.hessian2.whitelist";
|
||||
String ALLOW = "dubbo.application.hessian2.allow";
|
||||
String DENY = "dubbo.application.hessian2.deny";
|
||||
private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
|
||||
private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
|
||||
|
||||
private final Hessian2AllowClassManager hessian2AllowClassManager;
|
||||
|
||||
public Hessian2FactoryManager(FrameworkModel frameworkModel) {
|
||||
hessian2AllowClassManager = new Hessian2AllowClassManager(frameworkModel);
|
||||
}
|
||||
|
||||
public SerializerFactory getSerializerFactory(ClassLoader classLoader) {
|
||||
if (classLoader == null) {
|
||||
// system classloader
|
||||
if (SYSTEM_SERIALIZER_FACTORY == null) {
|
||||
synchronized (this) {
|
||||
if (SYSTEM_SERIALIZER_FACTORY == null) {
|
||||
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SYSTEM_SERIALIZER_FACTORY;
|
||||
}
|
||||
|
||||
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
|
||||
synchronized (this) {
|
||||
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
|
||||
SerializerFactory serializerFactory = createSerializerFactory();
|
||||
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
|
||||
return serializerFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CL_2_SERIALIZER_FACTORY.get(classLoader);
|
||||
}
|
||||
|
||||
private SerializerFactory createSerializerFactory() {
|
||||
String whitelist = System.getProperty(WHITELIST);
|
||||
if (StringUtils.isNotEmpty(whitelist)) {
|
||||
return createWhiteListSerializerFactory();
|
||||
}
|
||||
|
||||
return createDefaultSerializerFactory();
|
||||
}
|
||||
|
||||
private SerializerFactory createDefaultSerializerFactory() {
|
||||
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(hessian2AllowClassManager);
|
||||
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(hessian2AllowClassManager);
|
||||
String whiteList = System.getProperty(WHITELIST);
|
||||
if ("true".equals(whiteList)) {
|
||||
serializerFactory.getClassFactory().setWhitelist(true);
|
||||
String allowPattern = System.getProperty(ALLOW);
|
||||
if (StringUtils.isNotEmpty(allowPattern)) {
|
||||
for (String pattern : allowPattern.split(";")) {
|
||||
serializerFactory.getClassFactory().allow(pattern);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
serializerFactory.getClassFactory().setWhitelist(false);
|
||||
String denyPattern = System.getProperty(DENY);
|
||||
if (StringUtils.isNotEmpty(denyPattern)) {
|
||||
for (String pattern : denyPattern.split(";")) {
|
||||
serializerFactory.getClassFactory().deny(pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
|
||||
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
|
||||
return serializerFactory;
|
||||
}
|
||||
|
||||
public void onRemoveClassLoader(ClassLoader classLoader) {
|
||||
CL_2_SERIALIZER_FACTORY.remove(classLoader);
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.serialize.Cleanable;
|
||||
import org.apache.dubbo.common.serialize.ObjectInput;
|
||||
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
|
||||
|
||||
@ -31,12 +31,19 @@ import java.lang.reflect.Type;
|
||||
*/
|
||||
public class Hessian2ObjectInput implements ObjectInput, Cleanable {
|
||||
private final Hessian2Input mH2i;
|
||||
private final Hessian2FactoryInitializer hessian2FactoryInitializer;
|
||||
private final Hessian2FactoryManager hessian2FactoryManager;
|
||||
|
||||
@Deprecated
|
||||
public Hessian2ObjectInput(InputStream is) {
|
||||
mH2i = new Hessian2Input(is);
|
||||
hessian2FactoryInitializer = Hessian2FactoryInitializer.getInstance();
|
||||
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
|
||||
this.hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
|
||||
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
|
||||
public Hessian2ObjectInput(InputStream is, Hessian2FactoryManager hessian2FactoryManager) {
|
||||
mH2i = new Hessian2Input(is);
|
||||
this.hessian2FactoryManager = hessian2FactoryManager;
|
||||
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,7 +94,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
|
||||
@Override
|
||||
public Object readObject() throws IOException {
|
||||
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
|
||||
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
|
||||
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
return mH2i.readObject();
|
||||
}
|
||||
@ -97,7 +104,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
|
||||
public <T> T readObject(Class<T> cls) throws IOException,
|
||||
ClassNotFoundException {
|
||||
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
|
||||
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
|
||||
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
return (T) mH2i.readObject(cls);
|
||||
}
|
||||
@ -105,7 +112,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
|
||||
@Override
|
||||
public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
|
||||
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
|
||||
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
|
||||
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
return readObject(cls);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.serialize.Cleanable;
|
||||
import org.apache.dubbo.common.serialize.ObjectOutput;
|
||||
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
|
||||
|
||||
@ -32,9 +32,16 @@ public class Hessian2ObjectOutput implements ObjectOutput, Cleanable {
|
||||
|
||||
private final Hessian2Output mH2o;
|
||||
|
||||
@Deprecated
|
||||
public Hessian2ObjectOutput(OutputStream os) {
|
||||
mH2o = new Hessian2Output(os);
|
||||
mH2o.setSerializerFactory(Hessian2FactoryInitializer.getInstance().getSerializerFactory());
|
||||
Hessian2FactoryManager hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
|
||||
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
|
||||
public Hessian2ObjectOutput(OutputStream os, Hessian2FactoryManager hessian2FactoryManager) {
|
||||
mH2o = new Hessian2Output(os);
|
||||
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
|
||||
public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
|
||||
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
|
||||
beanFactory.registerBean(Hessian2FactoryManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {
|
||||
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.serialize.ObjectInput;
|
||||
import org.apache.dubbo.common.serialize.ObjectOutput;
|
||||
import org.apache.dubbo.common.serialize.Serialization;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -36,6 +37,12 @@ import static org.apache.dubbo.common.serialize.Constants.HESSIAN2_SERIALIZATION
|
||||
*/
|
||||
public class Hessian2Serialization implements Serialization {
|
||||
|
||||
private final Hessian2FactoryManager hessian2FactoryManager;
|
||||
|
||||
public Hessian2Serialization(FrameworkModel frameworkModel) {
|
||||
hessian2FactoryManager = frameworkModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getContentTypeId() {
|
||||
return HESSIAN2_SERIALIZATION_ID;
|
||||
@ -48,12 +55,12 @@ public class Hessian2Serialization implements Serialization {
|
||||
|
||||
@Override
|
||||
public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
|
||||
return new Hessian2ObjectOutput(out);
|
||||
return new Hessian2ObjectOutput(out, hessian2FactoryManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectInput deserialize(URL url, InputStream is) throws IOException {
|
||||
return new Hessian2ObjectInput(is);
|
||||
return new Hessian2ObjectInput(is, hessian2FactoryManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,14 @@ import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
public class Hessian2SerializerFactory extends SerializerFactory {
|
||||
|
||||
public Hessian2SerializerFactory() {
|
||||
private Hessian2AllowClassManager hessian2AllowClassManager;
|
||||
|
||||
public Hessian2SerializerFactory(Hessian2AllowClassManager hessian2AllowClassManager) {
|
||||
this.hessian2AllowClassManager = hessian2AllowClassManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadSerializedClass(String className) throws ClassNotFoundException {
|
||||
return hessian2AllowClassManager.loadClass(getClassLoader(), className);
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2.dubbo;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class AbstractHessian2FactoryInitializer implements Hessian2FactoryInitializer {
|
||||
private static final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
|
||||
private static volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
|
||||
|
||||
@Override
|
||||
public SerializerFactory getSerializerFactory() {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (classLoader == null) {
|
||||
// system classloader
|
||||
if (SYSTEM_SERIALIZER_FACTORY == null) {
|
||||
synchronized (AbstractHessian2FactoryInitializer.class) {
|
||||
if (SYSTEM_SERIALIZER_FACTORY == null) {
|
||||
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SYSTEM_SERIALIZER_FACTORY;
|
||||
}
|
||||
|
||||
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
|
||||
synchronized (AbstractHessian2FactoryInitializer.class) {
|
||||
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
|
||||
SerializerFactory serializerFactory = createSerializerFactory();
|
||||
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
|
||||
return serializerFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CL_2_SERIALIZER_FACTORY.get(classLoader);
|
||||
}
|
||||
|
||||
protected abstract SerializerFactory createSerializerFactory();
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2.dubbo;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
@SPI(value = "default", scope = ExtensionScope.FRAMEWORK)
|
||||
public interface Hessian2FactoryInitializer {
|
||||
String ALLOW = System.getProperty("dubbo.application.hessian2.allow");
|
||||
String DENY = System.getProperty("dubbo.application.hessian2.deny");
|
||||
String WHITELIST = System.getProperty("dubbo.application.hessian2.whitelist");
|
||||
|
||||
String ALLOW_NON_SERIALIZABLE = System.getProperty("dubbo.hessian.allowNonSerializable", "false");
|
||||
|
||||
SerializerFactory getSerializerFactory();
|
||||
|
||||
static Hessian2FactoryInitializer getInstance() {
|
||||
ExtensionLoader<Hessian2FactoryInitializer> loader = FrameworkModel.defaultModel().getExtensionLoader(Hessian2FactoryInitializer.class);
|
||||
if (StringUtils.isNotEmpty(WHITELIST)) {
|
||||
return loader.getExtension("whitelist");
|
||||
}
|
||||
return loader.getDefaultExtension();
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.dubbo.common.serialize.hessian2.dubbo;
|
||||
|
||||
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
|
||||
|
||||
/**
|
||||
* see https://github.com/ebourg/hessian/commit/cf851f5131707891e723f7f6a9718c2461aed826
|
||||
*/
|
||||
public class WhitelistHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
|
||||
|
||||
@Override
|
||||
public SerializerFactory createSerializerFactory() {
|
||||
SerializerFactory serializerFactory = new Hessian2SerializerFactory();
|
||||
if ("true".equals(WHITELIST)) {
|
||||
serializerFactory.getClassFactory().setWhitelist(true);
|
||||
if (StringUtils.isNotEmpty(ALLOW)) {
|
||||
for (String pattern : ALLOW.split(";")) {
|
||||
serializerFactory.getClassFactory().allow(pattern);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
serializerFactory.getClassFactory().setWhitelist(false);
|
||||
if (StringUtils.isNotEmpty(DENY)) {
|
||||
for (String pattern : DENY.split(";")) {
|
||||
serializerFactory.getClassFactory().deny(pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(ALLOW_NON_SERIALIZABLE));
|
||||
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
|
||||
return serializerFactory;
|
||||
}
|
||||
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
default=org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer
|
||||
whitelist=org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer
|
@ -0,0 +1 @@
|
||||
hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2ScopeModelInitializer
|
Loading…
Reference in New Issue
Block a user