diff --git a/.github/workflows/build-and-test-pr.yml b/.github/workflows/build-and-test-pr.yml index 0c85032f645..025e3a8c32d 100644 --- a/.github/workflows/build-and-test-pr.yml +++ b/.github/workflows/build-and-test-pr.yml @@ -199,7 +199,6 @@ jobs: env: DISABLE_FILE_SYSTEM_TEST: true CURRENT_ROLE: ${{ matrix.case-role }} - DUBBO_DEFAULT_SERIALIZATION: fastjson2 steps: - uses: actions/checkout@v3 with: diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java b/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java index 023830cd264..65aa66702fa 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.config.ConfigurationCache; import org.apache.dubbo.common.convert.ConverterUtil; import org.apache.dubbo.common.lang.ShutdownHookCallbacks; +import org.apache.dubbo.common.serialization.ClassHolder; import org.apache.dubbo.common.ssl.CertManager; import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; @@ -40,6 +41,7 @@ public void initializeFrameworkModel(FrameworkModel frameworkModel) { beanFactory.registerBean(SerializeSecurityManager.class); beanFactory.registerBean(DefaultSerializeClassChecker.class); beanFactory.registerBean(CertManager.class); + beanFactory.registerBean(ClassHolder.class); } @Override diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/serialization/ClassHolder.java b/dubbo-common/src/main/java/org/apache/dubbo/common/serialization/ClassHolder.java new file mode 100644 index 00000000000..4dd61511e4c --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/serialization/ClassHolder.java @@ -0,0 +1,46 @@ +/* + * 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.serialization; + +import org.apache.dubbo.common.utils.ConcurrentHashSet; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class ClassHolder { + private final Map>> classCache = new ConcurrentHashMap<>(); + + public void storeClass(Class clazz) { + classCache + .computeIfAbsent(clazz.getName(), k -> new ConcurrentHashSet<>()) + .add(clazz); + } + + public Class loadClass(String className, ClassLoader classLoader) { + Set> classList = classCache.get(className); + if (classList == null) { + return null; + } + for (Class clazz : classList) { + if (classLoader.equals(clazz.getClassLoader())) { + return clazz; + } + } + return null; + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/DefaultSerializeClassChecker.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/DefaultSerializeClassChecker.java index 7155a1eaa9c..029f654abd2 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/DefaultSerializeClassChecker.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/DefaultSerializeClassChecker.java @@ -16,8 +16,10 @@ */ package org.apache.dubbo.common.utils; +import org.apache.dubbo.common.aot.NativeDetector; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.serialization.ClassHolder; import org.apache.dubbo.rpc.model.FrameworkModel; import java.io.Serializable; @@ -40,6 +42,7 @@ public class DefaultSerializeClassChecker implements AllowClassNotifyListener { private volatile boolean checkSerializable = true; private final SerializeSecurityManager serializeSecurityManager; + private final ClassHolder classHolder; private volatile long[] allowPrefixes = new long[0]; private volatile long[] disAllowPrefixes = new long[0]; @@ -47,6 +50,8 @@ public class DefaultSerializeClassChecker implements AllowClassNotifyListener { public DefaultSerializeClassChecker(FrameworkModel frameworkModel) { serializeSecurityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class); serializeSecurityManager.registerListener(this); + classHolder = + NativeDetector.inNativeImage() ? frameworkModel.getBeanFactory().getBean(ClassHolder.class) : null; } @Override @@ -120,7 +125,7 @@ public Class loadClass(ClassLoader classLoader, String className) throws Clas private Class loadClass0(ClassLoader classLoader, String className) throws ClassNotFoundException { if (checkStatus == SerializeCheckStatus.DISABLE) { - return ClassUtils.forName(className, classLoader); + return classForName(classLoader, className); } long hash = MAGIC_HASH_CODE; @@ -133,7 +138,7 @@ private Class loadClass0(ClassLoader classLoader, String className) throws Cl hash *= MAGIC_PRIME; if (Arrays.binarySearch(allowPrefixes, hash) >= 0) { - return ClassUtils.forName(className, classLoader); + return classForName(classLoader, className); } } @@ -190,7 +195,7 @@ private Class loadClass0(ClassLoader classLoader, String className) throws Cl } } - Class clazz = ClassUtils.forName(className, classLoader); + Class clazz = classForName(classLoader, className); if (serializeSecurityManager.getWarnedClasses().add(className)) { logger.warn( PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, @@ -204,6 +209,16 @@ private Class loadClass0(ClassLoader classLoader, String className) throws Cl return clazz; } + private Class classForName(ClassLoader classLoader, String className) throws ClassNotFoundException { + if (classHolder != null) { + Class aClass = classHolder.loadClass(className, classLoader); + if (aClass != null) { + return aClass; + } + } + return ClassUtils.forName(className, classLoader); + } + public static DefaultSerializeClassChecker getInstance() { return FrameworkModel.defaultModel().getBeanFactory().getBean(DefaultSerializeClassChecker.class); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/SerializeSecurityConfigurator.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/SerializeSecurityConfigurator.java index 468e412b2cb..ea80a698a68 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/SerializeSecurityConfigurator.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/SerializeSecurityConfigurator.java @@ -16,9 +16,11 @@ */ package org.apache.dubbo.common.utils; +import org.apache.dubbo.common.aot.NativeDetector; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.serialization.ClassHolder; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; @@ -52,6 +54,8 @@ public class SerializeSecurityConfigurator implements ScopeClassLoaderListener clazz) { Set markedClass = new HashSet<>(); checkClass(markedClass, clazz); - addToAllow(clazz.getName()); + addToAllow(clazz); Method[] methodsToExport = clazz.getMethods(); @@ -291,7 +297,7 @@ private void checkClass(Set markedClass, Class clazz) { return; } - addToAllow(clazz.getName()); + addToAllow(clazz); if (ClassUtils.isSimpleType(clazz) || clazz.isPrimitive() || clazz.isArray()) { return; @@ -337,11 +343,17 @@ private void checkClass(Set markedClass, Class clazz) { } } - private void addToAllow(String className) { + private void addToAllow(Class clazz) { + if (classHolder != null) { + classHolder.storeClass(clazz); + } + + String className = clazz.getName(); // ignore jdk if (className.startsWith("java.") || className.startsWith("javax.") || className.startsWith("com.sun.") + || className.startsWith("jakarta.") || className.startsWith("sun.") || className.startsWith("jdk.")) { serializeSecurityManager.addToAllowed(className); diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java index bcccd7e1338..9b2966a05b4 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java @@ -481,7 +481,7 @@ void testLoadConfig() { public static class TestPreferSerializationProvider implements PreferSerializationProvider { @Override public String getPreferSerialization() { - return "fastjson2,hessian2"; + return "hessian2"; } } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java index 3c86651c6c3..c10c8eefc25 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java @@ -389,7 +389,7 @@ void testPreferSerializationDefault1() throws Exception { assertNull(protocolConfig.getPreferSerialization()); protocolConfig.checkDefault(); - assertThat(protocolConfig.getPreferSerialization(), equalTo("fastjson2,hessian2")); + assertThat(protocolConfig.getPreferSerialization(), equalTo("hessian2,fastjson2")); protocolConfig = new ProtocolConfig(); protocolConfig.setSerialization("x-serialization"); @@ -405,7 +405,7 @@ void testPreferSerializationDefault2() throws Exception { assertNull(protocolConfig.getPreferSerialization()); protocolConfig.refresh(); - assertThat(protocolConfig.getPreferSerialization(), equalTo("fastjson2,hessian2")); + assertThat(protocolConfig.getPreferSerialization(), equalTo("hessian2,fastjson2")); protocolConfig = new ProtocolConfig(); protocolConfig.setSerialization("x-serialization"); diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index ab13f35f2d3..ed2db220777 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -122,6 +122,11 @@ dubbo-serialization-fastjson2 ${project.version} + + org.apache.dubbo + dubbo-serialization-hessian2 + ${project.version} + org.apache.dubbo @@ -134,11 +139,6 @@ ${project.version} - - com.alibaba - fastjson - - org.apache.dubbo dubbo-native diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/org/apache/dubbo/demo/graalvm/consumer/Application.java b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/org/apache/dubbo/demo/graalvm/consumer/Application.java index cbe1fd58af3..1c9ebb64e5e 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/org/apache/dubbo/demo/graalvm/consumer/Application.java +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/org/apache/dubbo/demo/graalvm/consumer/Application.java @@ -36,7 +36,7 @@ public class Application { public static void main(String[] args) { SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_APPLICATION_LOGGER, "logback"); System.setProperty("native", "true"); - SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_PREFER_JSON_FRAMEWORK_NAME, "fastjson"); + SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_PREFER_JSON_FRAMEWORK_NAME, "fastjson2"); runWithBootstrap(); } @@ -55,7 +55,7 @@ private static void runWithBootstrap() { reference.setGeneric("false"); ProtocolConfig protocolConfig = new ProtocolConfig(CommonConstants.DUBBO, -1); - protocolConfig.setSerialization("fastjson2"); + protocolConfig.setSerialization("hessian2"); bootstrap .application(applicationConfig) .registry(new RegistryConfig(REGISTRY_URL)) diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index 39471b6dbd2..bf312f59657 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -122,6 +122,11 @@ dubbo-serialization-fastjson2 ${project.version} + + org.apache.dubbo + dubbo-serialization-hessian2 + ${project.version} + org.apache.dubbo @@ -133,10 +138,6 @@ dubbo-filter-validation ${project.version} - - com.alibaba - fastjson - org.apache.dubbo diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java index 8294638eca0..c0a4e9e4fd2 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java @@ -36,7 +36,7 @@ public class Application { public static void main(String[] args) throws Exception { SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_APPLICATION_LOGGER, "logback"); System.setProperty("native", "true"); - SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_PREFER_JSON_FRAMEWORK_NAME, "fastjson"); + SystemPropertyConfigUtils.setSystemProperty(DubboProperty.DUBBO_PREFER_JSON_FRAMEWORK_NAME, "fastjson2"); startWithBootstrap(); System.in.read(); } @@ -60,7 +60,7 @@ private static void startWithBootstrap() { service.setRef(new DemoServiceImpl()); ProtocolConfig protocolConfig = new ProtocolConfig(CommonConstants.DUBBO, -1); - protocolConfig.setSerialization("fastjson2"); + protocolConfig.setSerialization("hessian2"); bootstrap .application(applicationConfig) .registry(new RegistryConfig(REGISTRY_URL)) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index d50b16f3cc7..d538054c7b2 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -167,7 +167,7 @@ 2.2.7 1.2.0 1.19.7 - 3.2.13 + 4.0.0 1.6.14 1.1.10.5 @@ -364,7 +364,7 @@ ${hessian_version} - com.alibaba + org.apache.dubbo hessian-lite ${hessian_lite_version} diff --git a/dubbo-distribution/dubbo-all-shaded/pom.xml b/dubbo-distribution/dubbo-all-shaded/pom.xml index f9207588e36..b7426c4d7b1 100644 --- a/dubbo-distribution/dubbo-all-shaded/pom.xml +++ b/dubbo-distribution/dubbo-all-shaded/pom.xml @@ -427,7 +427,7 @@ snakeyaml - com.alibaba + org.apache.dubbo hessian-lite diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index dceb0307b12..15de10a5186 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -456,7 +456,7 @@ snakeyaml - com.alibaba + org.apache.dubbo hessian-lite diff --git a/dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java b/dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java index f924e4a714b..d1bb9bc931c 100644 --- a/dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java +++ b/dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java @@ -19,6 +19,9 @@ import org.apache.dubbo.aot.api.JdkProxyDescriber; import org.apache.dubbo.aot.api.ProxyDescriberRegistrar; import org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar; +import org.apache.dubbo.aot.api.ResourceBundleDescriber; +import org.apache.dubbo.aot.api.ResourceDescriberRegistrar; +import org.apache.dubbo.aot.api.ResourcePatternDescriber; import org.apache.dubbo.aot.api.TypeDescriber; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -46,6 +49,12 @@ public static void main(String[] args) { ResourceScanner.INSTANCE.distinctSpiResource().toArray(new String[] {})); resourceRepository.registerIncludesPatterns( ResourceScanner.INSTANCE.distinctSecurityResource().toArray(new String[] {})); + for (ResourcePatternDescriber resourcePatternDescriber : getResourcePatternDescribers()) { + resourceRepository.registerIncludesPattern(resourcePatternDescriber); + } + for (ResourceBundleDescriber resourceBundleDescriber : getResourceBundleDescribers()) { + resourceRepository.registerBundles(resourceBundleDescriber); + } writer.writeResourceConfig(resourceRepository); ReflectConfigMetadataRepository reflectRepository = new ReflectConfigMetadataRepository(); @@ -89,6 +98,52 @@ private static List getTypes() { return typeDescribers; } + private static List getResourcePatternDescribers() { + List resourcePatternDescribers = new ArrayList<>(); + FrameworkModel.defaultModel() + .defaultApplication() + .getExtensionLoader(ResourceDescriberRegistrar.class) + .getSupportedExtensionInstances() + .forEach(reflectionTypeDescriberRegistrar -> { + List describers = new ArrayList<>(); + try { + describers = reflectionTypeDescriberRegistrar.getResourcePatternDescribers(); + } catch (Throwable e) { + // The ResourceDescriberRegistrar implementation classes are shaded, causing some unused + // classes to be loaded. + // When loading a dependent class may appear that cannot be found, it does not affect. + // ignore + } + + resourcePatternDescribers.addAll(describers); + }); + + return resourcePatternDescribers; + } + + private static List getResourceBundleDescribers() { + List resourceBundleDescribers = new ArrayList<>(); + FrameworkModel.defaultModel() + .defaultApplication() + .getExtensionLoader(ResourceDescriberRegistrar.class) + .getSupportedExtensionInstances() + .forEach(reflectionTypeDescriberRegistrar -> { + List describers = new ArrayList<>(); + try { + describers = reflectionTypeDescriberRegistrar.getResourceBundleDescribers(); + } catch (Throwable e) { + // The ResourceDescriberRegistrar implementation classes are shaded, causing some unused + // classes to be loaded. + // When loading a dependent class may appear that cannot be found, it does not affect. + // ignore + } + + resourceBundleDescribers.addAll(describers); + }); + + return resourceBundleDescribers; + } + private static List getProxyDescribers() { List jdkProxyDescribers = new ArrayList<>(); FrameworkModel.defaultModel() diff --git a/dubbo-rpc/dubbo-rpc-api/pom.xml b/dubbo-rpc/dubbo-rpc-api/pom.xml index 40d072ed269..fc50ca0d840 100644 --- a/dubbo-rpc/dubbo-rpc-api/pom.xml +++ b/dubbo-rpc/dubbo-rpc-api/pom.xml @@ -47,7 +47,7 @@ ${project.parent.version} - com.alibaba + org.apache.dubbo hessian-lite test diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java index 402600fe3b0..014e026c908 100644 --- a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java +++ b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java @@ -28,7 +28,7 @@ public class PreferSerializationProviderImpl implements PreferSerializationProvi private final String preferSerialization; public PreferSerializationProviderImpl(FrameworkModel frameworkModel) { - List defaultSerializations = Arrays.asList("fastjson2", "hessian2"); + List defaultSerializations = Arrays.asList("hessian2", "fastjson2"); this.preferSerialization = defaultSerializations.stream() .filter(s -> frameworkModel.getExtensionLoader(Serialization.class).hasExtension(s)) diff --git a/dubbo-serialization/dubbo-serialization-hessian2/pom.xml b/dubbo-serialization/dubbo-serialization-hessian2/pom.xml index c6ba6bd6fa4..0342a5e766a 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/pom.xml +++ b/dubbo-serialization/dubbo-serialization-hessian2/pom.xml @@ -37,7 +37,7 @@ limitations under the License. ${project.parent.version} - com.alibaba + org.apache.dubbo hessian-lite @@ -45,5 +45,11 @@ limitations under the License. log4j-slf4j-impl test + + org.apache.dubbo + dubbo-native + ${project.parent.version} + + diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java index e8138942929..4f02609dfe6 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java @@ -25,6 +25,8 @@ import com.alibaba.com.caucho.hessian.io.JavaSerializer; import com.alibaba.com.caucho.hessian.io.Serializer; import com.alibaba.com.caucho.hessian.io.SerializerFactory; +import com.alibaba.com.caucho.hessian.io.UnsafeDeserializer; +import com.alibaba.com.caucho.hessian.io.UnsafeSerializer; public class Hessian2SerializerFactory extends SerializerFactory { @@ -54,7 +56,9 @@ protected Serializer getDefaultSerializer(Class cl) { checkSerializable(cl); - return new JavaSerializer(cl, getClassLoader()); + if (isEnableUnsafeSerializer() && JavaSerializer.getWriteReplace(cl) == null) { + return UnsafeSerializer.create(cl); + } else return JavaSerializer.create(cl); } @Override @@ -68,7 +72,9 @@ protected Deserializer getDefaultDeserializer(Class cl) { checkSerializable(cl); - return new JavaDeserializer(cl); + if (isEnableUnsafeSerializer()) { + return new UnsafeDeserializer(cl, getFieldDeserializerFactory()); + } else return new JavaDeserializer(cl, getFieldDeserializerFactory()); } private void checkSerializable(Class cl) { diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianReflectionTypeDescriberRegistrar.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianReflectionTypeDescriberRegistrar.java new file mode 100644 index 00000000000..0c44aa6572e --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianReflectionTypeDescriberRegistrar.java @@ -0,0 +1,100 @@ +/* + * 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.aot; + +import org.apache.dubbo.aot.api.MemberCategory; +import org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar; +import org.apache.dubbo.aot.api.TypeDescriber; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.alibaba.com.caucho.hessian.io.BigDecimalDeserializer; +import com.alibaba.com.caucho.hessian.io.FileDeserializer; +import com.alibaba.com.caucho.hessian.io.HessianRemote; +import com.alibaba.com.caucho.hessian.io.LocaleSerializer; +import com.alibaba.com.caucho.hessian.io.ObjectNameDeserializer; +import com.alibaba.com.caucho.hessian.io.StringValueSerializer; +import com.alibaba.com.caucho.hessian.io.java8.DurationSerializer; +import com.alibaba.com.caucho.hessian.io.java8.InstantSerializer; +import com.alibaba.com.caucho.hessian.io.java8.LocalDateSerializer; +import com.alibaba.com.caucho.hessian.io.java8.LocalDateTimeSerializer; +import com.alibaba.com.caucho.hessian.io.java8.LocalTimeSerializer; +import com.alibaba.com.caucho.hessian.io.java8.MonthDaySerializer; +import com.alibaba.com.caucho.hessian.io.java8.OffsetDateTimeSerializer; +import com.alibaba.com.caucho.hessian.io.java8.OffsetTimeSerializer; +import com.alibaba.com.caucho.hessian.io.java8.PeriodSerializer; +import com.alibaba.com.caucho.hessian.io.java8.YearMonthSerializer; +import com.alibaba.com.caucho.hessian.io.java8.YearSerializer; +import com.alibaba.com.caucho.hessian.io.java8.ZoneIdSerializer; +import com.alibaba.com.caucho.hessian.io.java8.ZoneOffsetSerializer; +import com.alibaba.com.caucho.hessian.io.java8.ZonedDateTimeSerializer; + +public class HessianReflectionTypeDescriberRegistrar implements ReflectionTypeDescriberRegistrar { + + @Override + public List getTypeDescribers() { + List typeDescribers = new ArrayList<>(); + typeDescribers.add(buildTypeDescriberWithDeclared(BigDecimalDeserializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(FileDeserializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(HessianRemote.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(LocaleSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(ObjectNameDeserializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(StringValueSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(DurationSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(InstantSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(LocalDateSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(LocalDateTimeSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(LocalTimeSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(MonthDaySerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(OffsetDateTimeSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(OffsetTimeSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(PeriodSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(YearMonthSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(YearSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(ZoneIdSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(ZoneOffsetSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(ZonedDateTimeSerializer.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(Date.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(Time.class)); + typeDescribers.add(buildTypeDescriberWithDeclared(Timestamp.class)); + + return typeDescribers; + } + + private TypeDescriber buildTypeDescriberWithDeclared(Class cl) { + Set memberCategories = new HashSet<>(); + memberCategories.add(MemberCategory.INVOKE_DECLARED_METHODS); + memberCategories.add(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + memberCategories.add(MemberCategory.DECLARED_FIELDS); + return new TypeDescriber( + cl.getName(), null, new HashSet<>(), new HashSet<>(), new HashSet<>(), memberCategories); + } + + private TypeDescriber buildTypeDescriberWithDeclared(String cl) { + Set memberCategories = new HashSet<>(); + memberCategories.add(MemberCategory.INVOKE_DECLARED_METHODS); + memberCategories.add(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + memberCategories.add(MemberCategory.DECLARED_FIELDS); + return new TypeDescriber(cl, null, new HashSet<>(), new HashSet<>(), new HashSet<>(), memberCategories); + } +} diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianResourceDescriberRegistrar.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianResourceDescriberRegistrar.java new file mode 100644 index 00000000000..daae432f501 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/aot/HessianResourceDescriberRegistrar.java @@ -0,0 +1,36 @@ +/* + * 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.aot; + +import org.apache.dubbo.aot.api.ResourceBundleDescriber; +import org.apache.dubbo.aot.api.ResourceDescriberRegistrar; +import org.apache.dubbo.aot.api.ResourcePatternDescriber; + +import java.util.Collections; +import java.util.List; + +public class HessianResourceDescriberRegistrar implements ResourceDescriberRegistrar { + @Override + public List getResourcePatternDescribers() { + return Collections.singletonList(new ResourcePatternDescriber("DENY_CLASS", null)); + } + + @Override + public List getResourceBundleDescribers() { + return Collections.emptyList(); + } +} diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar new file mode 100644 index 00000000000..bd5df8a4d7c --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar @@ -0,0 +1 @@ +hessian=org.apache.dubbo.common.serialize.hessian2.aot.HessianReflectionTypeDescriberRegistrar diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ResourceDescriberRegistrar b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ResourceDescriberRegistrar new file mode 100644 index 00000000000..b0c728b6dbf --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.aot.api.ResourceDescriberRegistrar @@ -0,0 +1 @@ +hessian=org.apache.dubbo.common.serialize.hessian2.aot.HessianResourceDescriberRegistrar diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization index 47d4cf2701e..637cc2b4bff 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization @@ -1 +1 @@ -hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization \ No newline at end of file +hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java index 559ed1e3b6a..b28443c90a8 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java @@ -206,7 +206,7 @@ void testReadEvent() throws IOException, ClassNotFoundException { } @Test - void testReadByte() throws IOException { + void testReadByte() throws IOException, ClassNotFoundException { FrameworkModel frameworkModel = new FrameworkModel(); Serialization serialization = frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2"); @@ -219,6 +219,19 @@ void testReadByte() throws IOException { objectOutput.writeObject((byte) 11); objectOutput.flushBuffer(); + byte[] bytes = outputStream.toByteArray(); + ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); + ObjectInput objectInput = serialization.deserialize(url, inputStream); + Assertions.assertEquals((byte) 11, objectInput.readObject()); + } + + // write byte, read byte + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ObjectOutput objectOutput = serialization.serialize(url, outputStream); + objectOutput.writeByte((byte) 11); + objectOutput.flushBuffer(); + byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); diff --git a/dubbo-serialization/dubbo-serialization-jdk/pom.xml b/dubbo-serialization/dubbo-serialization-jdk/pom.xml index 3c9fe679dc5..53009e13c8e 100644 --- a/dubbo-serialization/dubbo-serialization-jdk/pom.xml +++ b/dubbo-serialization/dubbo-serialization-jdk/pom.xml @@ -37,7 +37,7 @@ limitations under the License. ${project.parent.version} - com.alibaba + org.apache.dubbo hessian-lite