From 637b5d80cae6424ce1a74d8233357ace17ca1e5a Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 4 Dec 2023 21:32:50 +0800 Subject: [PATCH] Support exclude fastjson2 or hessian2 serialization dependencies (#13441) * Support exclude fastjson2 or hessian2 serialization dependencies * Fix style * Support check * Fix test cases * lint * Fix test cases * Style --- .../PreferSerializationProvider.java} | 13 ++---- .../apache/dubbo/config/ProtocolConfig.java | 9 +++- .../config/context/ConfigManagerTest.java | 10 +++++ .../dubbo/config/ProtocolConfigTest.java | 25 +++++------ .../TestPreferSerializationProvider.java | 26 ++++++++++++ .../SerializationScopeModelInitializer.java | 36 ++++++++++++++++ .../PreferSerializationProviderImpl.java | 42 +++++++++++++++++++ ...ache.dubbo.rpc.model.ScopeModelInitializer | 1 + .../fastjson2/FastJson2Serialization.java | 15 +++++++ .../Fastjson2ScopeModelInitializer.java | 14 +++++-- .../Hessian2ScopeModelInitializer.java | 14 +++++-- .../hessian2/Hessian2Serialization.java | 16 +++++++ 12 files changed, 188 insertions(+), 33 deletions(-) rename dubbo-common/src/main/java/org/apache/dubbo/common/{constants/ProviderConstants.java => serialization/PreferSerializationProvider.java} (75%) create mode 100644 dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/TestPreferSerializationProvider.java create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationScopeModelInitializer.java create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/ProviderConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/serialization/PreferSerializationProvider.java similarity index 75% rename from dubbo-common/src/main/java/org/apache/dubbo/common/constants/ProviderConstants.java rename to dubbo-common/src/main/java/org/apache/dubbo/common/serialization/PreferSerializationProvider.java index e94540d328f..ee97ba58ce8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/ProviderConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/serialization/PreferSerializationProvider.java @@ -14,15 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.common.constants; +package org.apache.dubbo.common.serialization; -/** - * Provider Constants - */ -public interface ProviderConstants { - - /** - * Default prefer serialization,multiple separated by commas - */ - String DEFAULT_PREFER_SERIALIZATION = "fastjson2,hessian2"; +public interface PreferSerializationProvider { + String getPreferSerialization(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java index c6be90b3dbf..74a2fa7e49b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.config; +import org.apache.dubbo.common.serialization.PreferSerializationProvider; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.support.Parameter; @@ -29,7 +30,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREAD_POOL_EXHAUSTED_LISTENERS_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION; -import static org.apache.dubbo.common.constants.ProviderConstants.DEFAULT_PREFER_SERIALIZATION; /** * ProtocolConfig @@ -264,7 +264,12 @@ protected void checkDefault() { } if (StringUtils.isBlank(preferSerialization)) { - preferSerialization = serialization != null ? serialization : DEFAULT_PREFER_SERIALIZATION; + preferSerialization = serialization != null + ? serialization + : getScopeModel() + .getBeanFactory() + .getBean(PreferSerializationProvider.class) + .getPreferSerialization(); } } 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 5ddd74aad4f..90f5b00a8f1 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 @@ -16,6 +16,7 @@ */ package org.apache.dubbo.config.context; +import org.apache.dubbo.common.serialization.PreferSerializationProvider; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ConfigCenterConfig; @@ -27,6 +28,7 @@ import org.apache.dubbo.config.ProviderConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -64,6 +66,7 @@ public void init() { ApplicationModel applicationModel = ApplicationModel.defaultModel(); configManager = applicationModel.getApplicationConfigManager(); moduleConfigManager = applicationModel.getDefaultModule().getConfigManager(); + FrameworkModel.defaultModel().getBeanFactory().registerBean(TestPreferSerializationProvider.class); } @Test @@ -468,4 +471,11 @@ void testLoadConfig() { Assertions.assertFalse(moduleConfigManager.getConsumers().isEmpty()); } + + public static class TestPreferSerializationProvider implements PreferSerializationProvider { + @Override + public String getPreferSerialization() { + return "fastjson2,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 d15052b4ad4..26b5bc89b66 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 @@ -44,6 +44,7 @@ class ProtocolConfigTest { @BeforeEach public void setUp() { DubboBootstrap.reset(); + // FrameworkModel.defaultModel().getBeanFactory().registerBean(TestPreferSerializationProvider.class); } @AfterEach @@ -234,14 +235,14 @@ void testExtension() throws Exception { void testMetaData() { ProtocolConfig config = new ProtocolConfig(); Map metaData = config.getMetaData(); - Assertions.assertEquals(0, metaData.size(), "actual: "+metaData); + Assertions.assertEquals(0, metaData.size(), "actual: " + metaData); } @Test void testOverrideEmptyConfig() { int port = NetUtils.getAvailablePort(); - //dubbo.protocol.name=rest - //dubbo.protocol.port=port + // dubbo.protocol.name=rest + // dubbo.protocol.port=port SysProps.setProperty("dubbo.protocol.name", "rest"); SysProps.setProperty("dubbo.protocol.port", String.valueOf(port)); @@ -285,7 +286,7 @@ void testOverrideConfigByName() { void testOverrideConfigById() { int port = NetUtils.getAvailablePort(); SysProps.setProperty("dubbo.protocols.rest1.name", "rest"); - SysProps.setProperty("dubbo.protocols.rest1.port", String.valueOf(port)); + SysProps.setProperty("dubbo.protocols.rest1.port", String.valueOf(port)); try { ProtocolConfig protocolConfig = new ProtocolConfig(); @@ -316,8 +317,7 @@ void testCreateConfigFromPropsWithId() { try { DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application("test-app") - .initialize(); + bootstrap.application("test-app").initialize(); ConfigManager configManager = bootstrap.getConfigManager(); Collection protocols = configManager.getProtocols(); @@ -343,8 +343,7 @@ void testCreateConfigFromPropsWithName() { try { DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application("test-app") - .initialize(); + bootstrap.application("test-app").initialize(); ConfigManager configManager = bootstrap.getConfigManager(); Collection protocols = configManager.getProtocols(); @@ -370,8 +369,7 @@ void testCreateDefaultConfigFromProps() { try { DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application("test-app") - .initialize(); + bootstrap.application("test-app").initialize(); ConfigManager configManager = bootstrap.getConfigManager(); Collection protocols = configManager.getProtocols(); @@ -387,14 +385,13 @@ void testCreateDefaultConfigFromProps() { } } - @Test void testPreferSerializationDefault1() throws Exception { ProtocolConfig protocolConfig = new ProtocolConfig(); assertNull(protocolConfig.getPreferSerialization()); protocolConfig.checkDefault(); - assertThat(protocolConfig.getPreferSerialization(), equalTo(DEFAULT_PREFER_SERIALIZATION)); + assertThat(protocolConfig.getPreferSerialization(), equalTo("fastjson2,hessian2")); protocolConfig = new ProtocolConfig(); protocolConfig.setSerialization("x-serialization"); @@ -410,7 +407,7 @@ void testPreferSerializationDefault2() throws Exception { assertNull(protocolConfig.getPreferSerialization()); protocolConfig.refresh(); - assertThat(protocolConfig.getPreferSerialization(), equalTo(DEFAULT_PREFER_SERIALIZATION)); + assertThat(protocolConfig.getPreferSerialization(), equalTo("fastjson2,hessian2")); protocolConfig = new ProtocolConfig(); protocolConfig.setSerialization("x-serialization"); @@ -419,6 +416,4 @@ void testPreferSerializationDefault2() throws Exception { protocolConfig.refresh(); assertThat(protocolConfig.getPreferSerialization(), equalTo("x-serialization")); } - - } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/TestPreferSerializationProvider.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/TestPreferSerializationProvider.java new file mode 100644 index 00000000000..dd2d1f119f4 --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/TestPreferSerializationProvider.java @@ -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.config.utils; + +import org.apache.dubbo.common.serialization.PreferSerializationProvider; + +public class TestPreferSerializationProvider implements PreferSerializationProvider { + @Override + public String getPreferSerialization() { + return "fastjson2,hessian2"; + } +} diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationScopeModelInitializer.java b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationScopeModelInitializer.java new file mode 100644 index 00000000000..184bdb7df89 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationScopeModelInitializer.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; + +import org.apache.dubbo.common.serialize.support.PreferSerializationProviderImpl; +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 SerializationScopeModelInitializer implements ScopeModelInitializer { + @Override + public void initializeFrameworkModel(FrameworkModel frameworkModel) { + frameworkModel.getBeanFactory().registerBean(PreferSerializationProviderImpl.class); + } + + @Override + public void initializeApplicationModel(ApplicationModel applicationModel) {} + + @Override + public void initializeModuleModel(ModuleModel moduleModel) {} +} 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 new file mode 100644 index 00000000000..402600fe3b0 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/support/PreferSerializationProviderImpl.java @@ -0,0 +1,42 @@ +/* + * 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.support; + +import org.apache.dubbo.common.serialization.PreferSerializationProvider; +import org.apache.dubbo.common.serialize.Serialization; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class PreferSerializationProviderImpl implements PreferSerializationProvider { + private final String preferSerialization; + + public PreferSerializationProviderImpl(FrameworkModel frameworkModel) { + List defaultSerializations = Arrays.asList("fastjson2", "hessian2"); + this.preferSerialization = defaultSerializations.stream() + .filter(s -> + frameworkModel.getExtensionLoader(Serialization.class).hasExtension(s)) + .collect(Collectors.joining(",")); + } + + @Override + public String getPreferSerialization() { + return preferSerialization; + } +} diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer b/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer new file mode 100644 index 00000000000..224d8115803 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer @@ -0,0 +1 @@ +serialization-api=org.apache.dubbo.common.serialize.SerializationScopeModelInitializer diff --git a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2Serialization.java b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2Serialization.java index 74ad821d545..a0e2af40cb4 100644 --- a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2Serialization.java +++ b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2Serialization.java @@ -22,6 +22,8 @@ import java.util.Optional; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.serialize.ObjectInput; import org.apache.dubbo.common.serialize.ObjectOutput; import org.apache.dubbo.common.serialize.Serialization; @@ -37,6 +39,19 @@ * */ public class FastJson2Serialization implements Serialization { + private static final Logger logger = LoggerFactory.getLogger(FastJson2Serialization.class); + + static { + Class aClass = null; + try { + aClass = com.alibaba.fastjson2.JSONB.class; + } catch (Throwable ignored) { + } + if (aClass == null) { + logger.info("Failed to load com.alibaba.fastjson2.JSONB, fastjson2 serialization will be disabled."); + throw new IllegalStateException("The fastjson2 is not in classpath."); + } + } @Override public byte getContentTypeId() { diff --git a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/Fastjson2ScopeModelInitializer.java b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/Fastjson2ScopeModelInitializer.java index db256cce384..5808e20e406 100644 --- a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/Fastjson2ScopeModelInitializer.java +++ b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/Fastjson2ScopeModelInitializer.java @@ -26,9 +26,17 @@ public class Fastjson2ScopeModelInitializer implements ScopeModelInitializer { @Override public void initializeFrameworkModel(FrameworkModel frameworkModel) { - ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); - beanFactory.registerBean(Fastjson2CreatorManager.class); - beanFactory.registerBean(Fastjson2SecurityManager.class); + Class aClass = null; + try { + aClass = com.alibaba.fastjson2.JSONB.class; + } catch (Throwable ignored) { + } + + if (aClass != null) { + ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); + beanFactory.registerBean(Fastjson2CreatorManager.class); + beanFactory.registerBean(Fastjson2SecurityManager.class); + } } @Override diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java index a86b39bdb8f..d3889bc7c5e 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java @@ -25,10 +25,18 @@ public class Hessian2ScopeModelInitializer implements ScopeModelInitializer { @Override public void initializeFrameworkModel(FrameworkModel frameworkModel) { - ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); - beanFactory.registerBean(Hessian2FactoryManager.class); + Class aClass = null; + try { + aClass = com.alibaba.com.caucho.hessian.io.Hessian2Output.class; + } catch (Throwable ignored) { + } - frameworkModel.addClassLoaderListener(new Hessian2ClassLoaderListener()); + if (aClass != null) { + ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); + beanFactory.registerBean(Hessian2FactoryManager.class); + + frameworkModel.addClassLoaderListener(new Hessian2ClassLoaderListener()); + } } @Override diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2Serialization.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2Serialization.java index 4ce04b026fc..517883cd6c1 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2Serialization.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2Serialization.java @@ -22,6 +22,8 @@ import java.util.Optional; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.serialize.ObjectInput; import org.apache.dubbo.common.serialize.ObjectOutput; import org.apache.dubbo.common.serialize.Serialization; @@ -37,6 +39,20 @@ * */ public class Hessian2Serialization implements Serialization { + private static final Logger logger = LoggerFactory.getLogger(Hessian2Serialization.class); + + static { + Class aClass = null; + try { + aClass = com.alibaba.com.caucho.hessian.io.Hessian2Output.class; + } catch (Throwable ignored) { + } + if (aClass == null) { + logger.info( + "Failed to load com.alibaba.com.caucho.hessian.io.Hessian2Output, hessian2 serialization will be disabled."); + throw new IllegalStateException("The hessian2 is not in classpath."); + } + } @Override public byte getContentTypeId() {