diff --git a/bom/pom.xml b/bom/pom.xml index a75784c55cb..969f8487e99 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -48,12 +48,12 @@ org.apache.seata - seata-threadpool + seata-spi-jdk17 ${project.version} org.apache.seata - seata-threadpool-loom + seata-spi-jdk21 ${project.version} diff --git a/common/pom.xml b/common/pom.xml index 5b157d750a4..947f30a7628 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -52,5 +52,20 @@ okhttp provided + + com.alibaba + fastjson + provided + + + com.alibaba.fastjson2 + fastjson2 + provided + + + com.google.code.gson + gson + provided + diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonAllowlistManager.java b/common/src/main/java/org/apache/seata/common/json/JsonAllowlistManager.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonAllowlistManager.java rename to common/src/main/java/org/apache/seata/common/json/JsonAllowlistManager.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonSerializer.java b/common/src/main/java/org/apache/seata/common/json/JsonSerializer.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonSerializer.java rename to common/src/main/java/org/apache/seata/common/json/JsonSerializer.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonSerializerFactory.java b/common/src/main/java/org/apache/seata/common/json/JsonSerializerFactory.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonSerializerFactory.java rename to common/src/main/java/org/apache/seata/common/json/JsonSerializerFactory.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/Fastjson2JsonSerializer.java b/common/src/main/java/org/apache/seata/common/json/impl/Fastjson2JsonSerializer.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/Fastjson2JsonSerializer.java rename to common/src/main/java/org/apache/seata/common/json/impl/Fastjson2JsonSerializer.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/FastjsonJsonSerializer.java b/common/src/main/java/org/apache/seata/common/json/impl/FastjsonJsonSerializer.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/FastjsonJsonSerializer.java rename to common/src/main/java/org/apache/seata/common/json/impl/FastjsonJsonSerializer.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/GsonJsonSerializer.java b/common/src/main/java/org/apache/seata/common/json/impl/GsonJsonSerializer.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/GsonJsonSerializer.java rename to common/src/main/java/org/apache/seata/common/json/impl/GsonJsonSerializer.java diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/JacksonJsonSerializer.java b/common/src/main/java/org/apache/seata/common/json/impl/JacksonJsonSerializer.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/impl/JacksonJsonSerializer.java rename to common/src/main/java/org/apache/seata/common/json/impl/JacksonJsonSerializer.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolExecutor.java b/common/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolExecutor.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolExecutor.java rename to common/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolExecutor.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolProvider.java b/common/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolProvider.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolProvider.java rename to common/src/main/java/org/apache/seata/common/thread/PlatformThreadPoolProvider.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolProvider.java b/common/src/main/java/org/apache/seata/common/thread/ThreadPoolProvider.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolProvider.java rename to common/src/main/java/org/apache/seata/common/thread/ThreadPoolProvider.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolProviderOrders.java b/common/src/main/java/org/apache/seata/common/thread/ThreadPoolProviderOrders.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolProviderOrders.java rename to common/src/main/java/org/apache/seata/common/thread/ThreadPoolProviderOrders.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolType.java b/common/src/main/java/org/apache/seata/common/thread/ThreadPoolType.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolType.java rename to common/src/main/java/org/apache/seata/common/thread/ThreadPoolType.java diff --git a/json-common/json-common-core/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer b/common/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer similarity index 100% rename from json-common/json-common-core/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer rename to common/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer diff --git a/threadpool/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider b/common/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider similarity index 100% rename from threadpool/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider rename to common/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider diff --git a/compatible/pom.xml b/compatible/pom.xml index 2ceb1ab96a0..b8e1d7e7aee 100644 --- a/compatible/pom.xml +++ b/compatible/pom.xml @@ -40,11 +40,6 @@ seata-saga-engine ${project.version} - - org.apache.seata - json-common-core - ${project.version} - org.apache.seata seata-saga-engine-store diff --git a/core/pom.xml b/core/pom.xml index e0b2395a499..48d5fd29f7c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -42,11 +42,6 @@ seata-discovery-core ${project.version} - - ${project.groupId} - seata-threadpool - ${project.version} - io.netty netty-all diff --git a/json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonUtil.java b/core/src/main/java/org/apache/seata/common/json/JsonUtil.java similarity index 100% rename from json-common/json-common-core/src/main/java/org/apache/seata/common/json/JsonUtil.java rename to core/src/main/java/org/apache/seata/common/json/JsonUtil.java diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java b/core/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java similarity index 97% rename from threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java rename to core/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java index e1b3090adf2..510c5c1fa36 100644 --- a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java +++ b/core/src/main/java/org/apache/seata/common/thread/ThreadPoolExecutorFactory.java @@ -165,9 +165,8 @@ private static ThreadPoolProvider resolveThreadPoolProvider() { // This second warning is intentionally kept to surface the per-request fallback // decision so that operators can correlate the missing-provider startup message // with the actual thread-pool mode that is in effect. - LOGGER.warn( - "Virtual thread pool was selected but the virtual-thread SPI provider (seata-threadpool-virtual) " - + "is not present on the classpath. Falling back to platform threads."); + LOGGER.warn("Virtual thread pool was selected but the virtual-thread SPI provider (seata-spi-jdk21) " + + "is not present on the classpath. Falling back to platform threads."); } return ThreadPoolProviderHolder.PLATFORM_THREAD_POOL_PROVIDER; } diff --git a/threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolRuntimeEnvironment.java b/core/src/main/java/org/apache/seata/common/thread/ThreadPoolRuntimeEnvironment.java similarity index 100% rename from threadpool/src/main/java/org/apache/seata/common/thread/ThreadPoolRuntimeEnvironment.java rename to core/src/main/java/org/apache/seata/common/thread/ThreadPoolRuntimeEnvironment.java diff --git a/threadpool/src/test/java/org/apache/seata/common/thread/ThreadPoolExecutorFactoryTest.java b/core/src/test/java/org/apache/seata/common/thread/ThreadPoolExecutorFactoryTest.java similarity index 100% rename from threadpool/src/test/java/org/apache/seata/common/thread/ThreadPoolExecutorFactoryTest.java rename to core/src/test/java/org/apache/seata/common/thread/ThreadPoolExecutorFactoryTest.java diff --git a/discovery/seata-discovery-consul/src/main/java/org/apache/seata/discovery/registry/consul/ConsulRegistryServiceImpl.java b/discovery/seata-discovery-consul/src/main/java/org/apache/seata/discovery/registry/consul/ConsulRegistryServiceImpl.java index 8aae9178716..4f0f222237b 100644 --- a/discovery/seata-discovery-consul/src/main/java/org/apache/seata/discovery/registry/consul/ConsulRegistryServiceImpl.java +++ b/discovery/seata-discovery-consul/src/main/java/org/apache/seata/discovery/registry/consul/ConsulRegistryServiceImpl.java @@ -22,7 +22,7 @@ import com.ecwid.consul.v1.agent.model.NewService; import com.ecwid.consul.v1.health.HealthServicesRequest; import com.ecwid.consul.v1.health.model.HealthService; -import org.apache.seata.common.thread.ThreadPoolExecutorFactory; +import org.apache.seata.common.thread.PlatformThreadPoolProvider; import org.apache.seata.common.util.NetUtil; import org.apache.seata.common.util.StringUtils; import org.apache.seata.config.Configuration; @@ -96,13 +96,16 @@ private ConsulRegistryServiceImpl() { clusterAddressMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); listenerMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); notifiers = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); - notifierExecutor = ThreadPoolExecutorFactory.newThreadPoolExecutor( - "services-consul-notifier", - THREAD_POOL_NUM, - THREAD_POOL_NUM, - Integer.MAX_VALUE, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>()); + notifierExecutor = new PlatformThreadPoolProvider() + .newThreadPoolExecutor( + "services-consul-notifier", + THREAD_POOL_NUM, + THREAD_POOL_NUM, + Integer.MAX_VALUE, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + true, + new java.util.concurrent.ThreadPoolExecutor.AbortPolicy()); } /** diff --git a/discovery/seata-discovery-core/pom.xml b/discovery/seata-discovery-core/pom.xml index ef149884506..98e7d06e5a4 100644 --- a/discovery/seata-discovery-core/pom.xml +++ b/discovery/seata-discovery-core/pom.xml @@ -35,12 +35,6 @@ seata-config-core ${project.version} - - ${project.groupId} - seata-threadpool - ${project.version} - - ch.qos.logback logback-classic diff --git a/discovery/seata-discovery-core/src/main/java/org/apache/seata/discovery/registry/RegistryHeartBeats.java b/discovery/seata-discovery-core/src/main/java/org/apache/seata/discovery/registry/RegistryHeartBeats.java index c85b16c3730..04864792bcc 100644 --- a/discovery/seata-discovery-core/src/main/java/org/apache/seata/discovery/registry/RegistryHeartBeats.java +++ b/discovery/seata-discovery-core/src/main/java/org/apache/seata/discovery/registry/RegistryHeartBeats.java @@ -16,7 +16,7 @@ */ package org.apache.seata.discovery.registry; -import org.apache.seata.common.thread.ThreadPoolExecutorFactory; +import org.apache.seata.common.thread.PlatformThreadPoolProvider; import org.apache.seata.config.Configuration; import org.apache.seata.config.ConfigurationFactory; import org.slf4j.Logger; @@ -24,6 +24,7 @@ import java.net.InetSocketAddress; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** @@ -42,8 +43,8 @@ public class RegistryHeartBeats { private static final long DEFAULT_HEARTBEAT_PERIOD = 60 * 1000; private static final boolean DEFAULT_HEARTBEAT_ENABLED = Boolean.TRUE; - private static final ScheduledExecutorService HEARTBEAT_SCHEDULED = - ThreadPoolExecutorFactory.newScheduledThreadPoolExecutor("seata-discovery-heartbeat", 1, true); + private static final ScheduledExecutorService HEARTBEAT_SCHEDULED = new PlatformThreadPoolProvider() + .newScheduledThreadPoolExecutor("seata-discovery-heartbeat", 1, true, new ThreadPoolExecutor.AbortPolicy()); public static void addHeartBeat(String registryType, InetSocketAddress serverAddress, ReRegister reRegister) { addHeartBeat(registryType, serverAddress, getHeartbeatPeriod(registryType), reRegister); diff --git a/discovery/seata-discovery-etcd3/src/main/java/org/apache/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java b/discovery/seata-discovery-etcd3/src/main/java/org/apache/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java index be5bf174a39..58697840451 100644 --- a/discovery/seata-discovery-etcd3/src/main/java/org/apache/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java +++ b/discovery/seata-discovery-etcd3/src/main/java/org/apache/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java @@ -28,7 +28,7 @@ import io.etcd.jetcd.options.WatchOption; import io.etcd.jetcd.watch.WatchResponse; import org.apache.seata.common.exception.ShouldNeverHappenException; -import org.apache.seata.common.thread.ThreadPoolExecutorFactory; +import org.apache.seata.common.thread.PlatformThreadPoolProvider; import org.apache.seata.common.util.NetUtil; import org.apache.seata.common.util.StringUtils; import org.apache.seata.config.Configuration; @@ -104,13 +104,16 @@ private EtcdRegistryServiceImpl() { clusterAddressMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); listenerMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); watcherMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); - executorService = ThreadPoolExecutorFactory.newThreadPoolExecutor( - "registry-etcd3", - THREAD_POOL_SIZE, - THREAD_POOL_SIZE, - Integer.MAX_VALUE, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>()); + executorService = new PlatformThreadPoolProvider() + .newThreadPoolExecutor( + "registry-etcd3", + THREAD_POOL_SIZE, + THREAD_POOL_SIZE, + Integer.MAX_VALUE, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + true, + new java.util.concurrent.ThreadPoolExecutor.AbortPolicy()); } /** diff --git a/discovery/seata-discovery-redis/src/main/java/org/apache/seata/discovery/registry/redis/RedisRegistryServiceImpl.java b/discovery/seata-discovery-redis/src/main/java/org/apache/seata/discovery/registry/redis/RedisRegistryServiceImpl.java index e7712f8d286..2741bcb1d18 100644 --- a/discovery/seata-discovery-redis/src/main/java/org/apache/seata/discovery/registry/redis/RedisRegistryServiceImpl.java +++ b/discovery/seata-discovery-redis/src/main/java/org/apache/seata/discovery/registry/redis/RedisRegistryServiceImpl.java @@ -19,7 +19,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.apache.seata.common.ConfigurationKeys; import org.apache.seata.common.exception.ShouldNeverHappenException; -import org.apache.seata.common.thread.ThreadPoolExecutorFactory; +import org.apache.seata.common.thread.PlatformThreadPoolProvider; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.common.util.NetUtil; import org.apache.seata.common.util.StringUtils; @@ -74,10 +74,19 @@ public class RedisRegistryServiceImpl implements RegistryService private String transactionServiceGroup; + private static final PlatformThreadPoolProvider THREAD_POOL_PROVIDER = new PlatformThreadPoolProvider(); private ScheduledExecutorService threadPoolExecutorForSubscribe = - ThreadPoolExecutorFactory.newScheduledThreadPoolExecutor("RedisRegistryService-subscribe", 1); + THREAD_POOL_PROVIDER.newScheduledThreadPoolExecutor( + "RedisRegistryService-subscribe", + 1, + true, + new java.util.concurrent.ThreadPoolExecutor.AbortPolicy()); private ScheduledExecutorService threadPoolExecutorForUpdateMap = - ThreadPoolExecutorFactory.newScheduledThreadPoolExecutor("RedisRegistryService-updateClusterAddrMap", 1); + THREAD_POOL_PROVIDER.newScheduledThreadPoolExecutor( + "RedisRegistryService-updateClusterAddrMap", + 1, + true, + new java.util.concurrent.ThreadPoolExecutor.AbortPolicy()); private RedisRegistryServiceImpl() { Configuration seataConfig = ConfigurationFactory.CURRENT_FILE_INSTANCE; diff --git a/integration-tx-api/pom.xml b/integration-tx-api/pom.xml index 46200183000..c08e5127e33 100644 --- a/integration-tx-api/pom.xml +++ b/integration-tx-api/pom.xml @@ -57,11 +57,6 @@ seata-common ${project.version} - - ${project.groupId} - json-common-core - ${project.version} - net.bytebuddy byte-buddy diff --git a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParser.java b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParser.java index 6fe82c5e01c..516672347df 100644 --- a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParser.java +++ b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParser.java @@ -19,7 +19,7 @@ import java.io.IOException; /** - * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in seata-common module instead. */ @Deprecated public interface JsonParser { diff --git a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserFactory.java b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserFactory.java index c5b38833a53..5f3bec98cc1 100644 --- a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserFactory.java +++ b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserFactory.java @@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; /** - * @deprecated use {@link org.apache.seata.common.json.JsonSerializerFactory} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonSerializerFactory} in seata-common module instead. */ @Deprecated public class JsonParserFactory { diff --git a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserWrap.java b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserWrap.java index a09b6054001..99bf50b1ace 100644 --- a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserWrap.java +++ b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/json/JsonParserWrap.java @@ -19,7 +19,7 @@ import org.apache.seata.common.exception.JsonParseException; /** - * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in seata-common module instead. */ @Deprecated public class JsonParserWrap implements JsonParser { diff --git a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/util/JsonUtil.java b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/util/JsonUtil.java index 23601b2a1b2..7963cc3e9d3 100644 --- a/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/util/JsonUtil.java +++ b/integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/util/JsonUtil.java @@ -25,7 +25,7 @@ import java.util.Objects; /** - * @deprecated use {@link org.apache.seata.common.json.JsonUtil} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonUtil} in seata-common module instead. */ @Deprecated public class JsonUtil { diff --git a/json-common/json-common-core/pom.xml b/json-common/json-common-core/pom.xml deleted file mode 100644 index 9c69f312cd1..00000000000 --- a/json-common/json-common-core/pom.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - org.apache.seata - json-common - ${revision} - - 4.0.0 - json-common-core - jar - json-common-core ${project.version} - jsonUtil core for Seata modules - - - - ${project.groupId} - seata-common - ${project.version} - - - ${project.groupId} - seata-core - ${project.version} - - - com.alibaba - fastjson - provided - - - com.alibaba.fastjson2 - fastjson2 - provided - - - com.fasterxml.jackson.core - jackson-databind - provided - - - com.google.code.gson - gson - provided - - - - diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2AllowlistTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2AllowlistTest.java deleted file mode 100644 index 16f6e1b9061..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2AllowlistTest.java +++ /dev/null @@ -1,231 +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.seata.common.json; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for Fastjson2 serializer with allowlist security check - */ -public class Fastjson2AllowlistTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - jsonSerializer = JsonSerializerFactory.getSerializer("fastjson2"); - } - - @AfterEach - void tearDown() { - JsonAllowlistManager.getInstance().clearUserAllowlist(); - } - - @Test - public void testParseObject_allowedSeataClass() { - - String json = - "{\"@type\":\"org.apache.seata.common.json.Fastjson2AllowlistTest$AllowedTestClass\",\"name\":\"test\"}"; - - AllowedTestClass result = jsonSerializer.parseObject(json, AllowedTestClass.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_allowedJavaClass() { - - String json = "{\"@type\":\"java.util.HashMap\"}"; - - Object result = jsonSerializer.parseObject(json, Object.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_notAllowedClass() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, Object.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("not in JSON deserialization allowlist") - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_userAllowedClass() { - - JsonAllowlistManager.getInstance().addUserClass("com.example.UserClass"); - - String json = "{\"@type\":\"com.example.UserClass\",\"data\":\"test\"}"; - - Assertions.assertDoesNotThrow(() -> jsonSerializer.parseObject(json, Object.class, false)); - } - - @Test - public void testParseObject_userAllowedPrefix() { - JsonAllowlistManager.getInstance().addUserPrefix("com.mycompany.model."); - - String json = "{\"@type\":\"com.mycompany.model.User\",\"id\":1}"; - - Assertions.assertDoesNotThrow(() -> jsonSerializer.parseObject(json, Object.class, false)); - } - - @Test - public void testParseObject_ignoreAutoType_bypasses_check() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - try { - jsonSerializer.parseObject(json, Object.class, true); - } catch (SecurityException e) { - throw new AssertionError("Should not throw SecurityException when ignoreAutoType=true", e); - } catch (Exception e) { - - assertThat(e).isNotInstanceOf(SecurityException.class); - } - } - - @Test - public void testParseObject_noAutoType_bypasses_check() { - - String json = "{\"name\":\"test\",\"value\":123}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_multipleAutoTypes() { - - String json = "{\"@type\":\"org.apache.seata.common.json.Fastjson2AllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"org.apache.seata.common.json.Fastjson2AllowlistTest$AllowedTestClass\",\"name\":\"nested\"}}"; - - ContainerClass result = jsonSerializer.parseObject(json, ContainerClass.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_multipleAutoTypes_oneNotAllowed() { - - String json = "{\"@type\":\"org.apache.seata.common.json.Fastjson2AllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"com.malicious.EvilClass\",\"name\":\"evil\"}}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, ContainerClass.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_atTypeInStringValue_notBlocked() { - String json = "{\"description\":\"the \\\"@type\\\" field is important\",\"name\":\"test\"}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testLoadUserAllowlist_thenParse() { - JsonAllowlistManager.getInstance().loadUserAllowlist("com.trusted.model.,com.trusted.dto.SpecificDTO"); - - String json1 = "{\"@type\":\"com.trusted.model.User\",\"id\":1}"; - try { - jsonSerializer.parseObject(json1, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json2 = "{\"@type\":\"com.trusted.dto.SpecificDTO\",\"data\":\"test\"}"; - try { - jsonSerializer.parseObject(json2, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json3 = "{\"@type\":\"com.untrusted.EvilClass\",\"data\":\"evil\"}"; - assertThatThrownBy(() -> jsonSerializer.parseObject(json3, Object.class, false)) - .isInstanceOf(SecurityException.class); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } - - public static class AllowedTestClass { - private String name; - - public AllowedTestClass() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - public static class ContainerClass { - private AllowedTestClass inner; - - public ContainerClass() {} - - public AllowedTestClass getInner() { - return inner; - } - - public void setInner(AllowedTestClass inner) { - this.inner = inner; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2JsonSerializerTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2JsonSerializerTest.java deleted file mode 100644 index 060cdc0d203..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/Fastjson2JsonSerializerTest.java +++ /dev/null @@ -1,320 +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.seata.common.json; - -import com.alibaba.fastjson2.TypeReference; -import org.apache.seata.common.exception.JsonParseException; -import org.apache.seata.common.json.impl.Fastjson2JsonSerializer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class Fastjson2JsonSerializerTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - jsonSerializer = JsonSerializerFactory.getSerializer("fastjson2"); - } - - @Test - public void testToJSONString_basicObject() { - TestObject obj = new TestObject("test", 123); - String json = jsonSerializer.toJSONString(obj); - - assertThat(json).contains("\"name\":\"test\""); - assertThat(json).contains("\"value\":123"); - } - - @Test - public void testParseObject_basicObject() { - String json = "{\"name\":\"test\",\"value\":123}"; - TestObject obj = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - } - - @Test - public void testToJSONString_and_parseObject() { - TestObject original = new TestObject("school", 456); - String json = jsonSerializer.toJSONString(original); - TestObject restored = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(restored.getName()).isEqualTo(original.getName()); - assertThat(restored.getValue()).isEqualTo(original.getValue()); - } - - @Test - public void testUseAutoType_withType() { - String json = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isTrue(); - } - - @Test - public void testUseAutoType_withoutType() { - String json = "{\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testToJSONString_prettyPrint() { - TestObject obj = new TestObject("pretty", 789); - String prettyJson = jsonSerializer.toJSONString(obj, true); - - assertThat(prettyJson).contains("\n"); - } - - @Test - public void testToJSONString_ignoreAutoType() { - TestObject obj = new TestObject("noType", 111); - String jsonWithoutType = jsonSerializer.toJSONString(obj, true, true); - - assertThat(jsonWithoutType).doesNotContain("@type"); - } - - @Test - public void testParseObject_ignoreAutoType() { - String json = jsonSerializer.toJSONString(new TestObject("ignored", 222)); - - TestObject obj = jsonSerializer.parseObject(json, TestObject.class, true); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("ignored"); - assertThat(obj.getValue()).isEqualTo(222); - } - - @Test - public void testEmptyList_serialization() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testEmptyList_deserialization() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testNullInput_toJSONString() { - String json = jsonSerializer.toJSONString(null); - assertThat(json).isEqualTo("null"); - } - - @Test - public void testNullInput_parseObject() { - TestObject obj = jsonSerializer.parseObject(null, TestObject.class); - assertThat(obj).isNull(); - - TestObject obj2 = jsonSerializer.parseObject("{}", null); - assertThat(obj2).isNull(); - } - - @Test - public void testParseObject_invalidJson() { - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Fastjson2 deserialize error"); - } - - @Test - public void testFactoryReturnsCorrectInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("fastjson2"); - assertThat(serializer).isNotNull(); - assertThat(serializer).isInstanceOf(Fastjson2JsonSerializer.class); - } - - @Test - public void testToJSONString_withAutoType() { - TestObject obj = new TestObject("withType", 789); - String jsonWithAutoType = jsonSerializer.toJSONString(obj, false, false); - - assertThat(jsonWithAutoType).contains("@type"); - } - - @Test - public void testParseObject_withAutoType() { - TestObject original = new TestObject("autoTypeTest", 999); - String jsonWithAutoType = jsonSerializer.toJSONString(original, false, false); - - TestObject restored = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("autoTypeTest"); - assertThat(restored.getValue()).isEqualTo(999); - } - - @Test - public void testParseObject_withType() { - String json = "{\"name\":\"test\",\"value\":123}"; - Type type = new TypeReference() {}.getType(); - - TestObject obj = jsonSerializer.parseObjectWithType(json, type); - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - - String listJson = "[{\"name\":\"item1\",\"value\":1},{\"name\":\"item2\",\"value\":2}]"; - Type listType = new TypeReference>() {}.getType(); - - List list = jsonSerializer.parseObjectWithType(listJson, listType); - assertThat(list).hasSize(2); - assertThat(list.get(0).getName()).isEqualTo("item1"); - assertThat(list.get(1).getValue()).isEqualTo(2); - } - - @Test - public void testParseObject_nullJson() { - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - } - - @Test - public void testParseObject_emptyList() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testParseObject_withIgnoreAutoType() { - String jsonWithAutoType = jsonSerializer.toJSONString(new TestObject("ignored", 222)); - - TestObject objIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, true); - assertThat(objIgnore).isNotNull(); - assertThat(objIgnore.getName()).isEqualTo("ignored"); - assertThat(objIgnore.getValue()).isEqualTo(222); - - TestObject objNoIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - assertThat(objNoIgnore).isNotNull(); - assertThat(objNoIgnore.getName()).isEqualTo("ignored"); - assertThat(objNoIgnore.getValue()).isEqualTo(222); - - List emptyList = jsonSerializer.parseObject("[]", List.class, false); - assertThat(emptyList).isEmpty(); - - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class, false)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Fastjson2 deserialize error"); - } - - /** - * The "[]" shortcut in parseObject(String, Class, boolean) must only apply when the - * target type is a Collection. Otherwise it would silently return an empty ArrayList - * cast to T, causing a ClassCastException at the call site. The exact behaviour of the - * underlying library when asked to map "[]" to a POJO may vary (return null, return an - * empty POJO, or throw); the only requirement enforced here is that the result is never - * an ArrayList. - */ - @Test - public void testParseObject_emptyArrayJson_nonCollectionType_doesNotReturnArrayList() { - assertEmptyArrayDoesNotProduceCollection(true); - assertEmptyArrayDoesNotProduceCollection(false); - } - - private void assertEmptyArrayDoesNotProduceCollection(boolean ignoreAutoType) { - Object result; - try { - result = jsonSerializer.parseObject("[]", TestObject.class, ignoreAutoType); - } catch (JsonParseException ignored) { - // throwing is also an acceptable outcome - return; - } - if (result != null) { - assertThat(result).isNotInstanceOf(java.util.Collection.class); - } - } - - @Test - public void testToJSONString_withIgnoreAutoTypeAndPrettyPrint() { - TestObject obj = new TestObject("noType", 111); - - String jsonIgnorePretty = jsonSerializer.toJSONString(obj, true, true); - assertThat(jsonIgnorePretty).contains("\n"); - assertThat(jsonIgnorePretty).doesNotContain("@type"); - - String jsonIgnoreNormal = jsonSerializer.toJSONString(obj, true, false); - assertThat(jsonIgnoreNormal).doesNotContain("\n"); - assertThat(jsonIgnoreNormal).doesNotContain("@type"); - - String jsonNoIgnorePretty = jsonSerializer.toJSONString(obj, false, true); - assertThat(jsonNoIgnorePretty).contains("\n"); - assertThat(jsonNoIgnorePretty).contains("@type"); - - String jsonNoIgnoreNormal = jsonSerializer.toJSONString(obj, false, false); - assertThat(jsonNoIgnoreNormal).doesNotContain("\n"); - assertThat(jsonNoIgnoreNormal).contains("@type"); - } - - @Test - public void testUseAutoType() { - String jsonWithAutoType = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - assertThat(jsonSerializer.useAutoType(jsonWithAutoType)).isTrue(); - - String jsonWithoutAutoType = "{\"name\":\"test\"}"; - assertThat(jsonSerializer.useAutoType(jsonWithoutAutoType)).isFalse(); - - String jsonWithTypeInValue = "{\"comment\":\"this has @type in it\"}"; - assertThat(jsonSerializer.useAutoType(jsonWithTypeInValue)).isFalse(); - - assertThat(jsonSerializer.useAutoType(null)).isFalse(); - - assertThat(jsonSerializer.useAutoType("")).isFalse(); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public TestObject(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonAllowlistTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonAllowlistTest.java deleted file mode 100644 index fc792c4ad0e..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonAllowlistTest.java +++ /dev/null @@ -1,232 +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.seata.common.json; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for FastJSON serializer with allowlist security check - */ -public class FastjsonAllowlistTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - jsonSerializer = JsonSerializerFactory.getSerializer("fastjson"); - } - - @AfterEach - void tearDown() { - JsonAllowlistManager.getInstance().clearUserAllowlist(); - } - - @Test - public void testParseObject_allowedSeataClass() { - - String json = - "{\"@type\":\"org.apache.seata.common.json.FastjsonAllowlistTest$AllowedTestClass\",\"name\":\"test\"}"; - - AllowedTestClass result = jsonSerializer.parseObject(json, AllowedTestClass.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_allowedJavaClass() { - - String json = "{\"@type\":\"java.util.HashMap\"}"; - - Object result = jsonSerializer.parseObject(json, Object.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_notAllowedClass() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, Object.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("not in JSON deserialization allowlist") - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_userAllowedClass() { - - JsonAllowlistManager.getInstance().addUserClass("com.example.UserClass"); - - String json = "{\"@type\":\"com.example.UserClass\",\"data\":\"test\"}"; - - Assertions.assertDoesNotThrow(() -> jsonSerializer.parseObject(json, Object.class, false)); - } - - @Test - public void testParseObject_userAllowedPrefix() { - JsonAllowlistManager.getInstance().addUserPrefix("com.mycompany.model."); - - String json = "{\"@type\":\"com.mycompany.model.User\",\"id\":1}"; - - Assertions.assertDoesNotThrow(() -> jsonSerializer.parseObject(json, Object.class, false)); - } - - @Test - public void testParseObject_ignoreAutoType_bypasses_check() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - try { - jsonSerializer.parseObject(json, Object.class, true); - } catch (SecurityException e) { - throw new AssertionError("Should not throw SecurityException when ignoreAutoType=true", e); - } catch (Exception e) { - - assertThat(e).isNotInstanceOf(SecurityException.class); - } - } - - @Test - public void testParseObject_noAutoType_bypasses_check() { - - String json = "{\"name\":\"test\",\"value\":123}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_multipleAutoTypes() { - - String json = "{\"@type\":\"org.apache.seata.common.json.FastjsonAllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"org.apache.seata.common.json.FastjsonAllowlistTest$AllowedTestClass\",\"name\":\"nested\"}}"; - - ContainerClass result = jsonSerializer.parseObject(json, ContainerClass.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_multipleAutoTypes_oneNotAllowed() { - - String json = "{\"@type\":\"org.apache.seata.common.json.FastjsonAllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"com.malicious.EvilClass\",\"name\":\"evil\"}}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, ContainerClass.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_atTypeInStringValue_notBlocked() { - // @type appearing inside a string value should not be treated as AutoType metadata - String json = "{\"description\":\"the \\\"@type\\\" field is important\",\"name\":\"test\"}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testLoadUserAllowlist_thenParse() { - JsonAllowlistManager.getInstance().loadUserAllowlist("com.trusted.model.,com.trusted.dto.SpecificDTO"); - - String json1 = "{\"@type\":\"com.trusted.model.User\",\"id\":1}"; - try { - jsonSerializer.parseObject(json1, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json2 = "{\"@type\":\"com.trusted.dto.SpecificDTO\",\"data\":\"test\"}"; - try { - jsonSerializer.parseObject(json2, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json3 = "{\"@type\":\"com.untrusted.EvilClass\",\"data\":\"evil\"}"; - assertThatThrownBy(() -> jsonSerializer.parseObject(json3, Object.class, false)) - .isInstanceOf(SecurityException.class); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } - - public static class AllowedTestClass { - private String name; - - public AllowedTestClass() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - public static class ContainerClass { - private AllowedTestClass inner; - - public ContainerClass() {} - - public AllowedTestClass getInner() { - return inner; - } - - public void setInner(AllowedTestClass inner) { - this.inner = inner; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonJsonSerializerTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonJsonSerializerTest.java deleted file mode 100644 index 15f752fb35f..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/FastjsonJsonSerializerTest.java +++ /dev/null @@ -1,312 +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.seata.common.json; - -import com.alibaba.fastjson.TypeReference; -import org.apache.seata.common.exception.JsonParseException; -import org.apache.seata.common.json.impl.FastjsonJsonSerializer; -import org.apache.seata.common.json.impl.JacksonJsonSerializer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class FastjsonJsonSerializerTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - // Use factory to get FastJSON serializer by name - jsonSerializer = JsonSerializerFactory.getSerializer("fastjson"); - } - - @Test - public void testToJSONString_basicObject() { - TestObject obj = new TestObject("test", 123); - String json = jsonSerializer.toJSONString(obj); - - assertThat(json).contains("\"name\":\"test\""); - assertThat(json).contains("\"value\":123"); - } - - @Test - public void testParseObject_basicObject() { - String json = "{\"name\":\"test\",\"value\":123}"; - TestObject obj = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - } - - @Test - public void testToJSONString_and_parseObject() { - TestObject original = new TestObject("school", 456); - String json = jsonSerializer.toJSONString(original); - TestObject restored = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(restored.getName()).isEqualTo(original.getName()); - assertThat(restored.getValue()).isEqualTo(original.getValue()); - } - - @Test - public void testUseAutoType_withType() { - String json = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isTrue(); - } - - @Test - public void testUseAutoType_withoutType() { - String json = "{\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testUseAutoType_typeInValue() { - String json = "{\"comment\":\"this has @type in it\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testToJSONString_prettyPrint() { - TestObject obj = new TestObject("pretty", 789); - String prettyJson = jsonSerializer.toJSONString(obj, true); - - assertThat(prettyJson).contains("\n"); - assertThat(prettyJson).contains("\t"); - } - - @Test - public void testToJSONString_ignoreAutoType() { - TestObject obj = new TestObject("noType", 111); - String jsonWithoutType = jsonSerializer.toJSONString(obj, true, true); - - assertThat(jsonWithoutType).doesNotContain("@type"); - } - - @Test - public void testParseObject_ignoreAutoType() { - String json = jsonSerializer.toJSONString(new TestObject("ignored", 222)); - - TestObject obj = jsonSerializer.parseObject(json, TestObject.class, true); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("ignored"); - assertThat(obj.getValue()).isEqualTo(222); - } - - @Test - public void testEmptyList_serialization() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testEmptyList_deserialization() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testNullInput_toJSONString() { - String json = jsonSerializer.toJSONString(null); - assertThat(json).isEqualTo("null"); - } - - @Test - public void testNullInput_parseObject() { - TestObject obj = jsonSerializer.parseObject(null, TestObject.class); - assertThat(obj).isNull(); - - TestObject obj2 = jsonSerializer.parseObject("{}", null); - assertThat(obj2).isNull(); - } - - @Test - public void testParseObject_invalidJson() { - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("FastJSON deserialize error"); - } - - @Test - public void testFactoryReturnsCorrectInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("fastjson"); - assertThat(serializer).isNotNull(); - assertThat(serializer).isInstanceOf(FastjsonJsonSerializer.class); - } - - @Test - public void testFactoryReturnsDefaultInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer(null); - assertThat(serializer).isNotNull(); - assertThat(serializer).isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testToJSONString_emptyList() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testToJSONString_withAutoType() { - TestObject obj = new TestObject("withType", 789); - String jsonWithAutoType = jsonSerializer.toJSONString(obj, false, false); - - assertThat(jsonWithAutoType).contains("@type"); - } - - @Test - public void testParseObject_nullJson() { - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - } - - @Test - public void testParseObject_emptyList() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testParseObject_withAutoType() { - TestObject original = new TestObject("autoTypeTest", 999); - String jsonWithAutoType = jsonSerializer.toJSONString(original, false, false); - - TestObject restored = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("autoTypeTest"); - assertThat(restored.getValue()).isEqualTo(999); - } - - @Test - public void testParseObject_withType() { - - String json = "{\"name\":\"test\",\"value\":123}"; - Type type = new TypeReference() {}.getType(); - - TestObject obj = jsonSerializer.parseObjectWithType(json, type); - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - - String listJson = "[{\"name\":\"item1\",\"value\":1},{\"name\":\"item2\",\"value\":2}]"; - Type listType = new TypeReference>() {}.getType(); - - List list = jsonSerializer.parseObjectWithType(listJson, listType); - assertThat(list).hasSize(2); - assertThat(list.get(0).getName()).isEqualTo("item1"); - assertThat(list.get(1).getValue()).isEqualTo(2); - } - - @Test - public void testParseObject_withIgnoreAutoType() { - - String jsonWithAutoType = jsonSerializer.toJSONString(new TestObject("ignored", 222)); - - TestObject objIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, true); - assertThat(objIgnore).isNotNull(); - assertThat(objIgnore.getName()).isEqualTo("ignored"); - assertThat(objIgnore.getValue()).isEqualTo(222); - - TestObject objNoIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - assertThat(objNoIgnore).isNotNull(); - assertThat(objNoIgnore.getName()).isEqualTo("ignored"); - assertThat(objNoIgnore.getValue()).isEqualTo(222); - - List emptyListResult = jsonSerializer.parseObject("", List.class, false); - assertThat(emptyListResult).isNull(); - - List emptyList = jsonSerializer.parseObject("[]", List.class, false); - assertThat(emptyList).isEmpty(); - - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class, false)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("FastJSON deserialize error"); - } - - /** - * The "[]" shortcut in parseObject(String, Class, boolean) must only apply when the - * target type is a Collection. Otherwise it would silently return an empty ArrayList - * cast to T, causing a ClassCastException at the call site. The exact behaviour of the - * underlying library when asked to map "[]" to a POJO may vary (return null, return an - * empty POJO, or throw); the only requirement enforced here is that the result is never - * an ArrayList. - */ - @Test - public void testParseObject_emptyArrayJson_nonCollectionType_doesNotReturnArrayList() { - assertEmptyArrayDoesNotProduceCollection(true); - assertEmptyArrayDoesNotProduceCollection(false); - } - - private void assertEmptyArrayDoesNotProduceCollection(boolean ignoreAutoType) { - Object result; - try { - result = jsonSerializer.parseObject("[]", TestObject.class, ignoreAutoType); - } catch (JsonParseException ignored) { - // throwing is also an acceptable outcome - return; - } - if (result != null) { - assertThat(result).isNotInstanceOf(java.util.Collection.class); - } - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public TestObject(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/GsonJsonSerializerTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/GsonJsonSerializerTest.java deleted file mode 100644 index ed2419912bd..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/GsonJsonSerializerTest.java +++ /dev/null @@ -1,265 +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.seata.common.json; - -import org.apache.seata.common.exception.JsonParseException; -import org.apache.seata.common.json.impl.GsonJsonSerializer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class GsonJsonSerializerTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - // Use factory to get Gson serializer by name - jsonSerializer = JsonSerializerFactory.getSerializer("gson"); - } - - @Test - public void testToJSONString_basicObject() { - TestObject obj = new TestObject("test", 123); - String json = jsonSerializer.toJSONString(obj); - - assertThat(json).contains("\"name\":\"test\""); - assertThat(json).contains("\"value\":123"); - assertThat(json).doesNotContain("@type"); - } - - @Test - public void testParseObject_basicObject() { - String json = "{\"name\":\"test\",\"value\":123}"; - TestObject obj = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - } - - @Test - public void testToJSONString_and_parseObject() { - TestObject original = new TestObject("school", 456); - String json = jsonSerializer.toJSONString(original); - TestObject restored = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(restored.getName()).isEqualTo(original.getName()); - assertThat(restored.getValue()).isEqualTo(original.getValue()); - } - - @Test - public void testUseAutoType_withType() { - String json = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testUseAutoType_withoutType() { - String json = "{\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testToJSONString_prettyPrint() { - TestObject obj = new TestObject("pretty", 789); - String prettyJson = jsonSerializer.toJSONString(obj, true); - - assertThat(prettyJson).contains("\n"); - assertThat(prettyJson).contains(" \""); - } - - @Test - public void testToJSONString_ignoreAutoType() { - TestObject obj = new TestObject("noType", 111); - String jsonWithoutType = jsonSerializer.toJSONString(obj, true, true); - - assertThat(jsonWithoutType).doesNotContain("@type"); - } - - @Test - public void testParseObject_ignoreAutoType() { - TestObject obj = new TestObject("ignored", 222); - String json = jsonSerializer.toJSONString(obj); - - TestObject restored = jsonSerializer.parseObject(json, TestObject.class, true); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("ignored"); - assertThat(restored.getValue()).isEqualTo(222); - } - - @Test - public void testEmptyList_serialization() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testEmptyList_deserialization() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testNullInput_toJSONString() { - String json = jsonSerializer.toJSONString(null); - assertThat(json).isEqualTo("null"); - } - - @Test - public void testNullInput_parseObject() { - TestObject obj = jsonSerializer.parseObject(null, TestObject.class); - assertThat(obj).isNull(); - - TestObject obj2 = jsonSerializer.parseObject("{}", null); - assertThat(obj2).isNull(); - } - - @Test - public void testParseObject_invalidJson() { - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Gson deserialize error"); - } - - @Test - public void testFactoryReturnsCorrectInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("gson"); - assertThat(serializer).isNotNull(); - assertThat(serializer).isInstanceOf(GsonJsonSerializer.class); - } - - @Test - public void testParseObject_nullText() { - assertThat(jsonSerializer.parseObject(null, String.class)).isNull(); - } - - @Test - public void testToJSONString_emptyList() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testToJSONString_withAutoType() { - TestObject obj = new TestObject("withType", 789); - String jsonWithAutoType = jsonSerializer.toJSONString(obj, false, false); - - assertThat(jsonWithAutoType).doesNotContain("@type"); - } - - @Test - public void testToJsonString_prettyPrint() { - TestObject obj = new TestObject("pretty", 789); - String prettyJson = jsonSerializer.toJSONString(obj, false, true); - - // Pretty JSON should contain newlines and indentation - assertThat(prettyJson).contains("\n"); - } - - @Test - public void testParseObject_nullJson() { - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - } - - @Test - public void testParseObject_emptyList() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - /** - * The "[]" shortcut in parseObject(String, Class, boolean) must only apply when the - * target type is a Collection. Otherwise it would silently return an empty ArrayList - * cast to T, causing a ClassCastException at the call site. The exact behaviour of the - * underlying library when asked to map "[]" to a POJO may vary (return null, return an - * empty POJO, or throw); the only requirement enforced here is that the result is never - * an ArrayList. - */ - @Test - public void testParseObject_emptyArrayJson_nonCollectionType_doesNotReturnArrayList() { - assertEmptyArrayDoesNotProduceCollection(true); - assertEmptyArrayDoesNotProduceCollection(false); - } - - private void assertEmptyArrayDoesNotProduceCollection(boolean ignoreAutoType) { - Object result; - try { - result = jsonSerializer.parseObject("[]", TestObject.class, ignoreAutoType); - } catch (JsonParseException ignored) { - // throwing is also an acceptable outcome - return; - } - if (result != null) { - assertThat(result).isNotInstanceOf(java.util.Collection.class); - } - } - - @Test - public void testParseObject_withAutoType() { - TestObject original = new TestObject("autoTypeTest", 999); - String jsonWithAutoType = jsonSerializer.toJSONString(original, false, false); - - TestObject restored = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("autoTypeTest"); - assertThat(restored.getValue()).isEqualTo(999); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() { - // Default constructor required for Gson - } - - public TestObject(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonAllowlistTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonAllowlistTest.java deleted file mode 100644 index 522b301a08c..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonAllowlistTest.java +++ /dev/null @@ -1,249 +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.seata.common.json; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for Jackson serializer with allowlist security check - */ -public class JacksonAllowlistTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - jsonSerializer = JsonSerializerFactory.getSerializer("jackson"); - } - - @AfterEach - void tearDown() { - JsonAllowlistManager.getInstance().clearUserAllowlist(); - } - - @Test - public void testParseObject_allowedSeataClass() { - - String json = - "{\"@type\":\"org.apache.seata.common.json.JacksonAllowlistTest$AllowedTestClass\",\"name\":\"test\"}"; - - AllowedTestClass result = jsonSerializer.parseObject(json, AllowedTestClass.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_allowedJavaClass() { - - String json = "{\"@type\":\"java.util.HashMap\"}"; - - Object result = jsonSerializer.parseObject(json, Object.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_notAllowedClass() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, Object.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("not in JSON deserialization allowlist") - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_userAllowedClass() { - - JsonAllowlistManager.getInstance().addUserClass("com.example.UserClass"); - - String json = "{\"@type\":\"com.example.UserClass\",\"data\":\"test\"}"; - - try { - jsonSerializer.parseObject(json, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - assertThat(e).isNotInstanceOf(SecurityException.class); - } - } - - @Test - public void testParseObject_userAllowedPrefix() { - JsonAllowlistManager.getInstance().addUserPrefix("com.mycompany.model."); - - String json = "{\"@type\":\"com.mycompany.model.User\",\"id\":1}"; - - try { - jsonSerializer.parseObject(json, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - assertThat(e).isNotInstanceOf(SecurityException.class); - } - } - - @Test - public void testParseObject_ignoreAutoType_bypasses_check() { - - String json = "{\"@type\":\"com.malicious.EvilClass\",\"command\":\"rm -rf /\"}"; - - try { - jsonSerializer.parseObject(json, Object.class, true); - } catch (SecurityException e) { - throw new AssertionError("Should not throw SecurityException when ignoreAutoType=true", e); - } catch (Exception e) { - - assertThat(e).isNotInstanceOf(SecurityException.class); - } - } - - @Test - public void testParseObject_noAutoType_bypasses_check() { - // Jackson's objectMapperWithAutoType requires @type for non-final types, - // so use the 2-arg parseObject (defaultObjectMapper, no AutoType) to verify - // that normal JSON without @type does not trigger any SecurityException. - String json = "{\"name\":\"test\",\"value\":123}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("test"); - } - - @Test - public void testParseObject_multipleAutoTypes() { - - String json = "{\"@type\":\"org.apache.seata.common.json.JacksonAllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"org.apache.seata.common.json.JacksonAllowlistTest$AllowedTestClass\",\"name\":\"nested\"}}"; - - ContainerClass result = jsonSerializer.parseObject(json, ContainerClass.class, false); - - assertThat(result).isNotNull(); - } - - @Test - public void testParseObject_multipleAutoTypes_oneNotAllowed() { - - String json = "{\"@type\":\"org.apache.seata.common.json.JacksonAllowlistTest$ContainerClass\"," - + "\"inner\":{\"@type\":\"com.malicious.EvilClass\",\"name\":\"evil\"}}"; - - assertThatThrownBy(() -> jsonSerializer.parseObject(json, ContainerClass.class, false)) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("com.malicious.EvilClass"); - } - - @Test - public void testParseObject_atTypeInStringValue_notBlocked() { - // @type appearing inside a string value should not be treated as AutoType metadata. - // The JSON has a real @type for the root object (required by Jackson's DefaultTyping), - // and a fake @type inside a string value which should not be flagged. - String json = "{\"@type\":\"org.apache.seata.common.json.JacksonAllowlistTest$TestObject\"," - + "\"name\":\"the \\\"@type\\\" field is important\",\"value\":123}"; - - TestObject result = jsonSerializer.parseObject(json, TestObject.class, false); - - assertThat(result).isNotNull(); - assertThat(result.getName()).isEqualTo("the \"@type\" field is important"); - } - - @Test - public void testLoadUserAllowlist_thenParse() { - JsonAllowlistManager.getInstance().loadUserAllowlist("com.trusted.model.,com.trusted.dto.SpecificDTO"); - - String json1 = "{\"@type\":\"com.trusted.model.User\",\"id\":1}"; - try { - jsonSerializer.parseObject(json1, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json2 = "{\"@type\":\"com.trusted.dto.SpecificDTO\",\"data\":\"test\"}"; - try { - jsonSerializer.parseObject(json2, Object.class, false); - } catch (SecurityException e) { - throw e; - } catch (Exception e) { - - } - - String json3 = "{\"@type\":\"com.untrusted.EvilClass\",\"data\":\"evil\"}"; - assertThatThrownBy(() -> jsonSerializer.parseObject(json3, Object.class, false)) - .isInstanceOf(SecurityException.class); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } - - public static class AllowedTestClass { - private String name; - - public AllowedTestClass() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - public static class ContainerClass { - private AllowedTestClass inner; - - public ContainerClass() {} - - public AllowedTestClass getInner() { - return inner; - } - - public void setInner(AllowedTestClass inner) { - this.inner = inner; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonJsonSerializerTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonJsonSerializerTest.java deleted file mode 100644 index 1433fb0ca2d..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JacksonJsonSerializerTest.java +++ /dev/null @@ -1,380 +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.seata.common.json; - -import com.alibaba.fastjson.TypeReference; -import org.apache.seata.common.exception.JsonParseException; -import org.apache.seata.common.json.impl.JacksonJsonSerializer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class JacksonJsonSerializerTest { - - private JsonSerializer jsonSerializer; - - @BeforeEach - void setUp() { - // Use factory to get Jackson serializer by name - jsonSerializer = JsonSerializerFactory.getSerializer("jackson"); - } - - @Test - public void testToJSONString_basicObject() { - TestObject obj = new TestObject("test", 123); - String json = jsonSerializer.toJSONString(obj); - - assertThat(json).contains("\"name\":\"test\""); - assertThat(json).contains("\"value\":123"); - } - - @Test - public void testParseObject_basicObject() { - String json = - "{\"@class\":\"org.apache.seata.common.json.JacksonJsonSerializerTest$TestObject\",\"name\":\"test\",\"value\":123}"; - TestObject obj = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - } - - @Test - public void testToJSONString_and_parseObject() { - TestObject original = new TestObject("school", 456); - String json = jsonSerializer.toJSONString(original); - TestObject restored = jsonSerializer.parseObject(json, TestObject.class); - - assertThat(restored.getName()).isEqualTo(original.getName()); - assertThat(restored.getValue()).isEqualTo(original.getValue()); - } - - @Test - public void testUseAutoType_withType() { - String json = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isTrue(); - } - - @Test - public void testUseAutoType_withoutType() { - String json = "{\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testUseAutoType_typeInValue() { - String json = "{\"comment\":\"this has @type in it\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(json); - assertThat(hasAutoType).isFalse(); - } - - @Test - public void testToJSONString_withAutoType() { - TestObject obj = new TestObject("withType", 789); - String jsonWithAutoType = jsonSerializer.toJSONString(obj, false, false); - - assertThat(jsonWithAutoType).isNotNull(); - assertThat(jsonWithAutoType).contains("@type"); - assertThat(jsonWithAutoType).contains("\"name\":\"withType\""); - assertThat(jsonWithAutoType).contains("\"value\":789"); - } - - @Test - public void testParseObject_withAutoType() { - TestObject original = new TestObject("autoTypeTest", 999); - // Serialize with autoType enabled - String jsonWithAutoType = jsonSerializer.toJSONString(original, false, false); - - // Deserialize with autoType enabled - TestObject restored = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("autoTypeTest"); - assertThat(restored.getValue()).isEqualTo(999); - } - - @Test - public void testEmptyList_serialization() { - List emptyList = new ArrayList<>(); - String json = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(json).isEqualTo("[]"); - } - - @Test - public void testEmptyList_deserialization() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testNullInput_toJSONString() { - String json = jsonSerializer.toJSONString(null); - assertThat(json).isEqualTo("null"); - } - - @Test - public void testNullInput_parseObject() { - TestObject obj = jsonSerializer.parseObject(null, TestObject.class); - assertThat(obj).isNull(); - - TestObject obj2 = jsonSerializer.parseObject("{}", null); - assertThat(obj2).isNull(); - } - - @Test - public void testParseObject_invalidJson() { - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Jackson deserialize error"); - } - - @Test - public void testFactoryReturnsCorrectInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("jackson"); - assertThat(serializer).isNotNull(); - assertThat(serializer).isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testFactoryReturnsDefaultInstance() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer(null); - assertThat(serializer).isNotNull(); - } - - @Test - public void testToJSONString_throwsException() { - Object unserializable = new Object() { - private final java.io.InputStream stream = System.in; - }; - - assertThatThrownBy(() -> jsonSerializer.toJSONString(unserializable)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Jackson serialize error"); - } - - @Test - public void testParseObject_nullText() { - assertThat(jsonSerializer.parseObject(null, String.class)).isNull(); - } - - @Test - public void testToJSONString_prettyPrint() { - TestObject obj = new TestObject("pretty", 789); - String prettyJson = jsonSerializer.toJSONString(obj, true); - - // Pretty JSON should contain newlines and indentation - assertThat(prettyJson).contains("\n"); - } - - @Test - public void testParseObject_nullJson() { - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - } - - @Test - public void testParseObject_emptyList() { - String json = "[]"; - List list = jsonSerializer.parseObject(json, List.class, false); - assertThat(list).isEmpty(); - } - - @Test - public void testParseObject_ignoreAutoType() { - TestObject obj = new TestObject("ignored", 222); - String json = jsonSerializer.toJSONString(obj); - - TestObject restored = jsonSerializer.parseObject(json, TestObject.class, true); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("ignored"); - assertThat(restored.getValue()).isEqualTo(222); - } - - @Test - public void testParseObject_withType() { - String json = - "{\"@type\":\"org.apache.seata.common.json.JacksonJsonSerializerTest$TestObject\",\"name\":\"test\",\"value\":123}"; - Type type = new TypeReference() {}.getType(); - - TestObject obj = jsonSerializer.parseObjectWithType(json, type); - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - - assertThatThrownBy(() -> jsonSerializer.parseObjectWithType("{invalid json}", type)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Jackson deserialize error"); - } - - @Test - public void testUseAutoType() { - String jsonWithAutoType = "{\"@type\":\"some.type\",\"name\":\"test\"}"; - boolean hasAutoType = jsonSerializer.useAutoType(jsonWithAutoType); - assertThat(hasAutoType).isTrue(); - - String jsonWithoutAutoType = "{\"name\":\"test\"}"; - boolean noAutoType = jsonSerializer.useAutoType(jsonWithoutAutoType); - assertThat(noAutoType).isFalse(); - - String jsonWithTypeInValue = "{\"comment\":\"this has @type in it\"}"; - boolean typeInValue = jsonSerializer.useAutoType(jsonWithTypeInValue); - assertThat(typeInValue).isFalse(); - - boolean nullAutoType = jsonSerializer.useAutoType(null); - assertThat(nullAutoType).isFalse(); - - boolean emptyAutoType = jsonSerializer.useAutoType(""); - assertThat(emptyAutoType).isFalse(); - } - - @Test - public void testToJSONString_withPrettyPrint() { - TestObject obj = new TestObject("pretty", 789); - - String prettyJson = jsonSerializer.toJSONString(obj, true); - assertThat(prettyJson).contains("\n"); - assertThat(prettyJson).contains("@type"); - - String normalJson = jsonSerializer.toJSONString(obj, false); - assertThat(normalJson).doesNotContain("\n"); - assertThat(normalJson).contains("@type"); - } - - @Test - public void testToJSONString_withIgnoreAutoTypeAndPrettyPrint() { - TestObject obj = new TestObject("noType", 111); - - String jsonIgnorePretty = jsonSerializer.toJSONString(obj, true, true); - assertThat(jsonIgnorePretty).contains("\n"); - assertThat(jsonIgnorePretty).doesNotContain("@type"); - - String jsonIgnoreNormal = jsonSerializer.toJSONString(obj, true, false); - assertThat(jsonIgnoreNormal).doesNotContain("\n"); - assertThat(jsonIgnoreNormal).doesNotContain("@type"); - - String jsonNoIgnorePretty = jsonSerializer.toJSONString(obj, false, true); - assertThat(jsonNoIgnorePretty).contains("\n"); - assertThat(jsonNoIgnorePretty).contains("@type"); - - String jsonNoIgnoreNormal = jsonSerializer.toJSONString(obj, false, false); - assertThat(jsonNoIgnoreNormal).doesNotContain("\n"); - assertThat(jsonNoIgnoreNormal).contains("@type"); - - List emptyList = new ArrayList<>(); - String emptyListJson = jsonSerializer.toJSONString(emptyList, false, false); - assertThat(emptyListJson).isEqualTo("[]"); - - Object invalidObject = new Object() { - private final java.io.InputStream stream = System.in; - }; - - assertThatThrownBy(() -> jsonSerializer.toJSONString(invalidObject, false, false)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Jackson serialize error"); - } - - /** - * The "[]" shortcut in parseObject(String, Class, boolean) must only apply when the - * target type is a Collection. Otherwise it would silently return an empty ArrayList - * cast to T, causing a ClassCastException at the call site. The exact behaviour of the - * underlying library when asked to map "[]" to a POJO may vary (return null, return an - * empty POJO, or throw); the only requirement enforced here is that the result is never - * an ArrayList. - */ - @Test - public void testParseObject_emptyArrayJson_nonCollectionType_doesNotReturnArrayList() { - assertEmptyArrayDoesNotProduceCollection(true); - assertEmptyArrayDoesNotProduceCollection(false); - } - - private void assertEmptyArrayDoesNotProduceCollection(boolean ignoreAutoType) { - Object result; - try { - result = jsonSerializer.parseObject("[]", TestObject.class, ignoreAutoType); - } catch (JsonParseException ignored) { - // throwing is also an acceptable outcome - return; - } - if (result != null) { - assertThat(result).isNotInstanceOf(java.util.Collection.class); - } - } - - @Test - public void testParseObject_withIgnoreAutoType() { - String jsonWithAutoType = jsonSerializer.toJSONString(new TestObject("ignored", 222), false, false); - - TestObject objIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, true); - assertThat(objIgnore).isNotNull(); - assertThat(objIgnore.getName()).isEqualTo("ignored"); - assertThat(objIgnore.getValue()).isEqualTo(222); - - TestObject objNoIgnore = jsonSerializer.parseObject(jsonWithAutoType, TestObject.class, false); - assertThat(objNoIgnore).isNotNull(); - assertThat(objNoIgnore.getName()).isEqualTo("ignored"); - assertThat(objNoIgnore.getValue()).isEqualTo(222); - - List emptyList = jsonSerializer.parseObject("[]", List.class, false); - assertThat(emptyList).isEmpty(); - - List emptyListIgnore = jsonSerializer.parseObject("[]", List.class, true); - assertThat(emptyListIgnore).isEmpty(); - - assertThat(jsonSerializer.parseObject(null, TestObject.class, false)).isNull(); - - assertThatThrownBy(() -> jsonSerializer.parseObject("{invalid json}", TestObject.class, false)) - .isInstanceOf(JsonParseException.class) - .hasMessageContaining("Jackson deserialize error"); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public TestObject(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonAllowlistManagerTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonAllowlistManagerTest.java deleted file mode 100644 index c33425308ba..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonAllowlistManagerTest.java +++ /dev/null @@ -1,340 +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.seata.common.json; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for {@link JsonAllowlistManager} - */ -public class JsonAllowlistManagerTest { - - @AfterEach - void tearDown() { - - JsonAllowlistManager.getInstance().clearUserAllowlist(); - } - - @Test - public void testBuiltinAllowlist_primitiveWrappers() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("java.lang.String")).isTrue(); - assertThat(manager.isAllowed("java.lang.Integer")).isTrue(); - assertThat(manager.isAllowed("java.lang.Long")).isTrue(); - assertThat(manager.isAllowed("java.lang.Boolean")).isTrue(); - assertThat(manager.isAllowed("java.lang.Double")).isTrue(); - assertThat(manager.isAllowed("java.lang.Float")).isTrue(); - assertThat(manager.isAllowed("java.lang.Byte")).isTrue(); - assertThat(manager.isAllowed("java.lang.Short")).isTrue(); - assertThat(manager.isAllowed("java.lang.Character")).isTrue(); - assertThat(manager.isAllowed("java.lang.Number")).isTrue(); - assertThat(manager.isAllowed("java.math.BigDecimal")).isTrue(); - assertThat(manager.isAllowed("java.math.BigInteger")).isTrue(); - } - - @Test - public void testBuiltinAllowlist_arrays() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - // 1D primitive arrays - assertThat(manager.isAllowed("[B")).isTrue(); - assertThat(manager.isAllowed("[I")).isTrue(); - assertThat(manager.isAllowed("[J")).isTrue(); - assertThat(manager.isAllowed("[Z")).isTrue(); - assertThat(manager.isAllowed("[C")).isTrue(); - assertThat(manager.isAllowed("[S")).isTrue(); - assertThat(manager.isAllowed("[F")).isTrue(); - assertThat(manager.isAllowed("[D")).isTrue(); - - // Multi-dimensional primitive arrays - assertThat(manager.isAllowed("[[I")).isTrue(); - assertThat(manager.isAllowed("[[Z")).isTrue(); - assertThat(manager.isAllowed("[[B")).isTrue(); - assertThat(manager.isAllowed("[[J")).isTrue(); - assertThat(manager.isAllowed("[[[D")).isTrue(); - assertThat(manager.isAllowed("[[[F")).isTrue(); - - // Object arrays - assertThat(manager.isAllowed("[Ljava.lang.String;")).isTrue(); - assertThat(manager.isAllowed("[Ljava.lang.Object;")).isTrue(); - } - - @Test - public void testBuiltinAllowlist_dateTime() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("java.util.Date")).isTrue(); - assertThat(manager.isAllowed("java.sql.Timestamp")).isTrue(); - assertThat(manager.isAllowed("java.time.LocalDateTime")).isTrue(); - assertThat(manager.isAllowed("java.time.LocalDate")).isTrue(); - assertThat(manager.isAllowed("java.time.Instant")).isTrue(); - assertThat(manager.isAllowed("java.time.ZonedDateTime")).isTrue(); - } - - @Test - public void testBuiltinAllowlist_collections() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("java.util.ArrayList")).isTrue(); - assertThat(manager.isAllowed("java.util.LinkedList")).isTrue(); - assertThat(manager.isAllowed("java.util.HashMap")).isTrue(); - assertThat(manager.isAllowed("java.util.LinkedHashMap")).isTrue(); - assertThat(manager.isAllowed("java.util.HashSet")).isTrue(); - assertThat(manager.isAllowed("java.util.TreeMap")).isTrue(); - assertThat(manager.isAllowed("java.util.concurrent.ConcurrentHashMap")).isTrue(); - } - - @Test - public void testBuiltinAllowlist_seataPrefix() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("org.apache.seata.core.model.BranchType")).isTrue(); - assertThat(manager.isAllowed("io.seata.saga.engine.mock.DemoService$People")) - .isTrue(); - assertThat(manager.isAllowed("org.apache.seata.rm.datasource.undo.UndoLogParser")) - .isTrue(); - assertThat(manager.isAllowed("org.apache.seata.common.json.JsonAllowlistManager")) - .isTrue(); - } - - @Test - public void testBuiltinAllowlist_objectArrayDescriptorsByPrefix() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("[Lorg.apache.seata.common.json.JsonAllowlistManager;")) - .isTrue(); - assertThat(manager.isAllowed("[Lio.seata.saga.engine.mock.DemoService$People;")) - .isTrue(); - assertThat(manager.isAllowed("[[Lio.seata.saga.engine.mock.DemoService$People;")) - .isTrue(); - assertThat(manager.isAllowed("[Lcom.malicious.EvilClass;")).isFalse(); - } - - @Test - public void testBuiltinAllowlist_objectArrayCanonicalNameByPrefix() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("io.seata.saga.engine.mock.DemoService$People[]")) - .isTrue(); - assertThat(manager.isAllowed("io.seata.saga.engine.mock.DemoService$People[][]")) - .isTrue(); - assertThat(manager.isAllowed("com.malicious.EvilClass[]")).isFalse(); - } - - @Test - public void testBuiltinAllowlist_notAllowed() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed("com.sun.rowset.JdbcRowSetImpl")).isFalse(); - assertThat(manager.isAllowed("java.lang.Runtime")).isFalse(); - assertThat(manager.isAllowed("java.lang.ProcessBuilder")).isFalse(); - assertThat(manager.isAllowed("javax.naming.InitialContext")).isFalse(); - assertThat(manager.isAllowed("com.example.MaliciousClass")).isFalse(); - } - - @Test - public void testLoadUserAllowlist_exactMatch() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.example.MyClass,com.example.AnotherClass"); - - assertThat(manager.isAllowed("com.example.MyClass")).isTrue(); - assertThat(manager.isAllowed("com.example.AnotherClass")).isTrue(); - assertThat(manager.isAllowed("com.example.NotInList")).isFalse(); - } - - @Test - public void testLoadUserAllowlist_prefixMatch() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.company.model.,com.company.dto."); - - assertThat(manager.isAllowed("com.company.model.User")).isTrue(); - assertThat(manager.isAllowed("com.company.model.Order")).isTrue(); - assertThat(manager.isAllowed("com.company.dto.UserDTO")).isTrue(); - assertThat(manager.isAllowed("com.company.service.UserService")).isFalse(); - } - - @Test - public void testLoadUserAllowlist_mixedMatch() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.company.model.,com.thirdparty.SpecificClass"); - - assertThat(manager.isAllowed("com.company.model.User")).isTrue(); - assertThat(manager.isAllowed("com.company.model.sub.NestedClass")).isTrue(); - assertThat(manager.isAllowed("com.thirdparty.SpecificClass")).isTrue(); - assertThat(manager.isAllowed("com.thirdparty.OtherClass")).isFalse(); - } - - @Test - public void testLoadUserAllowlist_withSpaces() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist(" com.example.Class1 , com.example.Class2 "); - - assertThat(manager.isAllowed("com.example.Class1")).isTrue(); - assertThat(manager.isAllowed("com.example.Class2")).isTrue(); - } - - @Test - public void testLoadUserAllowlist_emptyEntries() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.example.Class1,,com.example.Class2,"); - - assertThat(manager.isAllowed("com.example.Class1")).isTrue(); - assertThat(manager.isAllowed("com.example.Class2")).isTrue(); - } - - @Test - public void testLoadUserAllowlist_nullOrEmpty() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist(null); - manager.loadUserAllowlist(""); - - assertThat(manager.isAllowed("java.lang.String")).isTrue(); - } - - @Test - public void testAddUserClass() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.addUserClass("com.example.DynamicClass"); - - assertThat(manager.isAllowed("com.example.DynamicClass")).isTrue(); - } - - @Test - public void testAddUserPrefix() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.addUserPrefix("com.dynamic.pkg."); - - assertThat(manager.isAllowed("com.dynamic.pkg.Class1")).isTrue(); - assertThat(manager.isAllowed("com.dynamic.pkg.sub.Class2")).isTrue(); - } - - @Test - public void testClearUserAllowlist() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.example.ToBeCleared"); - assertThat(manager.isAllowed("com.example.ToBeCleared")).isTrue(); - - manager.clearUserAllowlist(); - assertThat(manager.isAllowed("com.example.ToBeCleared")).isFalse(); - - assertThat(manager.isAllowed("java.lang.String")).isTrue(); - } - - @Test - public void testCheckClass_allowed() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.checkClass("java.lang.String"); - manager.checkClass("java.util.ArrayList"); - manager.checkClass("org.apache.seata.core.model.BranchType"); - } - - @Test - public void testCheckClass_notAllowed() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThatThrownBy(() -> manager.checkClass("com.malicious.EvilClass")) - .isInstanceOf(SecurityException.class) - .hasMessageContaining("not in JSON deserialization allowlist") - .hasMessageContaining("com.malicious.EvilClass") - .hasMessageContaining("seata.json.allowlist"); - } - - @Test - public void testCheckClass_userAllowed() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.loadUserAllowlist("com.myapp.model."); - - manager.checkClass("com.myapp.model.User"); - } - - @Test - public void testIsAllowed_null() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThat(manager.isAllowed(null)).isFalse(); - } - - @Test - public void testCheckClass_null() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - assertThatThrownBy(() -> manager.checkClass(null)).isInstanceOf(SecurityException.class); - } - - @Test - public void testAddUserClass_nullOrEmpty() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.addUserClass(null); - manager.addUserClass(""); - } - - @Test - public void testAddUserPrefix_nullOrEmpty() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.addUserPrefix(null); - manager.addUserPrefix(""); - } - - @Test - public void testSingleton() { - JsonAllowlistManager instance1 = JsonAllowlistManager.getInstance(); - JsonAllowlistManager instance2 = JsonAllowlistManager.getInstance(); - - assertThat(instance1).isSameAs(instance2); - } - - @Test - public void testCacheWorks() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - boolean result1 = manager.isAllowed("java.lang.String"); - - boolean result2 = manager.isAllowed("java.lang.String"); - - assertThat(result1).isTrue(); - assertThat(result2).isTrue(); - } - - @Test - public void testCacheClearedOnLoadUserAllowlist() { - JsonAllowlistManager manager = JsonAllowlistManager.getInstance(); - - manager.isAllowed("com.example.CacheTest"); - - manager.loadUserAllowlist("com.example.CacheTest"); - - assertThat(manager.isAllowed("com.example.CacheTest")).isTrue(); - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonSerializerFactoryTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonSerializerFactoryTest.java deleted file mode 100644 index 99a66966f3e..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonSerializerFactoryTest.java +++ /dev/null @@ -1,145 +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.seata.common.json; - -import org.apache.seata.common.json.impl.Fastjson2JsonSerializer; -import org.apache.seata.common.json.impl.FastjsonJsonSerializer; -import org.apache.seata.common.json.impl.GsonJsonSerializer; -import org.apache.seata.common.json.impl.JacksonJsonSerializer; -import org.apache.seata.common.loader.EnhancedServiceNotFoundException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Field; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class JsonSerializerFactoryTest { - - @BeforeEach - @SuppressWarnings("unchecked") - void clearInstancesCache() throws Exception { - Field field = JsonSerializerFactory.class.getDeclaredField("INSTANCES"); - field.setAccessible(true); - ((Map) field.get(null)).clear(); - } - - @Test - public void testGetSerializer_jackson() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("jackson"); - assertThat(serializer).isNotNull().isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testGetSerializer_fastjson() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("fastjson"); - assertThat(serializer).isNotNull().isInstanceOf(FastjsonJsonSerializer.class); - } - - @Test - public void testGetSerializer_fastjson2() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("fastjson2"); - assertThat(serializer).isNotNull().isInstanceOf(Fastjson2JsonSerializer.class); - } - - @Test - public void testGetSerializer_gson() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("gson"); - assertThat(serializer).isNotNull().isInstanceOf(GsonJsonSerializer.class); - } - - @Test - public void testGetSerializer_nullName_returnsDefaultJackson() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer(null); - assertThat(serializer).isNotNull().isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testGetSerializer_unknownName_throwsException() { - assertThatThrownBy(() -> JsonSerializerFactory.getSerializer("definitely-not-a-real-serializer")) - .isInstanceOf(EnhancedServiceNotFoundException.class); - } - - @Test - public void testGetSerializer_sameNameReturnsCachedInstance() { - JsonSerializer first = JsonSerializerFactory.getSerializer("jackson"); - JsonSerializer second = JsonSerializerFactory.getSerializer("jackson"); - assertThat(second).isSameAs(first); - } - - /** - * In json-common-core tests, the jackson3 SPI lives in the separate json-common-jackson3 - * module which is NOT on the test classpath. The factory must catch the - * EnhancedServiceNotFoundException for "jackson3" and fall back to the default "jackson" - * serializer. - */ - @Test - public void testGetSerializer_jackson3_fallsBackToJacksonWhenUnavailable() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("jackson3"); - assertThat(serializer).isNotNull().isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testGetSerializer_jackson3FallbackIsCached() { - JsonSerializer first = JsonSerializerFactory.getSerializer("jackson3"); - JsonSerializer second = JsonSerializerFactory.getSerializer("jackson3"); - assertThat(second).isSameAs(first); - assertThat(first).isInstanceOf(JacksonJsonSerializer.class); - } - - @Test - public void testGetSerializer_jackson3FallbackIsUsableForSerialization() { - JsonSerializer serializer = JsonSerializerFactory.getSerializer("jackson3"); - String json = serializer.toJSONString(new SimplePojo("hello", 7)); - assertThat(json).contains("\"name\":\"hello\"").contains("\"value\":7"); - - SimplePojo restored = serializer.parseObject(json, SimplePojo.class); - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("hello"); - assertThat(restored.getValue()).isEqualTo(7); - } - - public static class SimplePojo { - private String name; - private int value; - - public SimplePojo() {} - - public SimplePojo(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } -} diff --git a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonUtilTest.java b/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonUtilTest.java deleted file mode 100644 index 2dab9ba4ecc..00000000000 --- a/json-common/json-common-core/src/test/java/org/apache/seata/common/json/JsonUtilTest.java +++ /dev/null @@ -1,202 +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.seata.common.json; - -import org.apache.seata.common.ConfigurationKeys; -import org.apache.seata.common.DefaultValues; -import org.apache.seata.config.Configuration; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class JsonUtilTest { - - @BeforeEach - void setUp() {} - - @Test - public void testToJSONStringBasicObject() { - TestObject obj = new TestObject("test", 123); - String json = JsonUtil.toJSONString(obj); - - assertThat(json).isNotNull(); - assertThat(json).contains("\"name\":\"test\""); - assertThat(json).contains("\"value\":123"); - } - - @Test - public void testParseObjectBasicObject() { - String json = "{\"name\":\"test\",\"value\":123}"; - TestObject obj = JsonUtil.parseObject(json, TestObject.class); - - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("test"); - assertThat(obj.getValue()).isEqualTo(123); - } - - @Test - public void testToJSONStringAndParseObjectApple() { - TestObject original = new TestObject("apple", 456); - String json = JsonUtil.toJSONString(original); - TestObject restored = JsonUtil.parseObject(json, TestObject.class); - - assertThat(restored.getName()).isEqualTo(original.getName()); - assertThat(restored.getValue()).isEqualTo(original.getValue()); - } - - @Test - public void testParseObjectNullInputs() { - TestObject obj1 = JsonUtil.parseObject(null, TestObject.class); - assertThat(obj1).isNull(); - - TestObject obj2 = JsonUtil.parseObject("{\"name\":\"test\"}", null); - assertThat(obj2).isNull(); - } - - @Test - public void testParseObjectPrefixLogic() { - String normalJson = "{\"name\":\"normalTest\",\"value\":888}"; - TestObject obj = JsonUtil.parseObject(normalJson, TestObject.class); - assertThat(obj).isNotNull(); - assertThat(obj.getName()).isEqualTo("normalTest"); - assertThat(obj.getValue()).isEqualTo(888); - } - - @Test - public void testToJSONStringNullObject() { - String json = JsonUtil.toJSONString(null); - assertThat(json).isEqualTo("null"); - } - - @Test - public void testParseObjectComplexObject() { - ComplexTestObject complexObj = new ComplexTestObject(); - complexObj.setName("complex"); - complexObj.setValue(789); - complexObj.setNested(new TestObject("nested", 1)); - - String json = JsonUtil.toJSONString(complexObj); - ComplexTestObject restored = JsonUtil.parseObject(json, ComplexTestObject.class); - - assertThat(restored).isNotNull(); - assertThat(restored.getName()).isEqualTo("complex"); - assertThat(restored.getValue()).isEqualTo(789); - assertThat(restored.getNested()).isNotNull(); - assertThat(restored.getNested().getName()).isEqualTo("nested"); - assertThat(restored.getNested().getValue()).isEqualTo(1); - } - - @Test - public void testResolveJsonSerializerNamePrefersNewConfig() { - Configuration configuration = mock(Configuration.class); - when(configuration.getConfig(ConfigurationKeys.JSON_SERIALIZER_TYPE)).thenReturn("gson"); - - assertThat(JsonUtil.resolveJsonSerializerName(configuration)).isEqualTo("gson"); - } - - @Test - public void testResolveJsonSerializerNameFallsBackToDeprecatedConfig() { - Configuration configuration = mock(Configuration.class); - when(configuration.getConfig(ConfigurationKeys.JSON_SERIALIZER_TYPE)).thenReturn(null); - when(configuration.getConfig(ConfigurationKeys.TCC_BUSINESS_ACTION_CONTEXT_JSON_PARSER_NAME)) - .thenReturn("fastjson2"); - - assertThat(JsonUtil.resolveJsonSerializerName(configuration)).isEqualTo("fastjson2"); - } - - @Test - public void testResolveJsonSerializerNameReturnsDefaultWhenConfigMissing() { - Configuration configuration = mock(Configuration.class); - when(configuration.getConfig(ConfigurationKeys.JSON_SERIALIZER_TYPE)).thenReturn(null); - when(configuration.getConfig(ConfigurationKeys.TCC_BUSINESS_ACTION_CONTEXT_JSON_PARSER_NAME)) - .thenReturn(null); - - assertThat(JsonUtil.resolveJsonSerializerName(configuration)) - .isEqualTo(DefaultValues.BUSINESS_ACTION_CONTEXT_JSON_PARSER); - } - - @Test - public void testResolveJsonSerializerNameIgnoresBlankNewConfigAndFallsBackToDeprecatedConfig() { - Configuration configuration = mock(Configuration.class); - when(configuration.getConfig(ConfigurationKeys.JSON_SERIALIZER_TYPE)).thenReturn(" "); - when(configuration.getConfig(ConfigurationKeys.TCC_BUSINESS_ACTION_CONTEXT_JSON_PARSER_NAME)) - .thenReturn("fastjson2"); - - assertThat(JsonUtil.resolveJsonSerializerName(configuration)).isEqualTo("fastjson2"); - } - - public static class TestObject { - private String name; - private int value; - - public TestObject() {} - - public TestObject(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } - - public static class ComplexTestObject { - private String name; - private int value; - private TestObject nested; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - - public TestObject getNested() { - return nested; - } - - public void setNested(TestObject nested) { - this.nested = nested; - } - } -} diff --git a/json-common/json-common-core/src/test/resources/file.conf b/json-common/json-common-core/src/test/resources/file.conf deleted file mode 100644 index 46c3e0401cc..00000000000 --- a/json-common/json-common-core/src/test/resources/file.conf +++ /dev/null @@ -1,25 +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. -# - -service { - #transaction service group mapping - vgroupMapping.default_tx_group = "default" - #only support when registry.type=file, please don't set multiple addresses - default.grouplist = "127.0.0.1:8091" - #disable seata - disableGlobalTransaction = false -} \ No newline at end of file diff --git a/json-common/json-common-core/src/test/resources/registry.conf b/json-common/json-common-core/src/test/resources/registry.conf deleted file mode 100644 index 5ad014bf55a..00000000000 --- a/json-common/json-common-core/src/test/resources/registry.conf +++ /dev/null @@ -1,34 +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. -# - -registry { - # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa - type = "file" - - file { - name = "file.conf" - } -} - -config { - # file、nacos 、apollo、zk、consul、etcd3 - type = "file" - - file { - name = "file.conf" - } -} \ No newline at end of file diff --git a/json-common/pom.xml b/json-common/pom.xml deleted file mode 100644 index 1c0d9a5b5ff..00000000000 --- a/json-common/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - org.apache.seata - seata-parent - ${revision} - - 4.0.0 - json-common - pom - json-common ${project.version} - json-common top parent for Seata built with Maven - - - json-common-core - - - - - - JDK17Plus - - [17,) - - - json-common-jackson3 - - - - - diff --git a/pom.xml b/pom.xml index 05129717f49..b2fb282f29f 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,6 @@ bom common config - threadpool core compatible @@ -63,7 +62,6 @@ test-suite/test-new-version test-suite/test-old-version test-suite/seata-benchmark-cli - json-common @@ -129,6 +127,16 @@ + + + JDK17Plus + + [17,) + + + spi-jdk17 + + JDK21Plus @@ -136,7 +144,7 @@ [21,) - threadpool-loom + spi-jdk21 diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml index c08172c2943..ddcb08734a8 100644 --- a/rm-datasource/pom.xml +++ b/rm-datasource/pom.xml @@ -159,10 +159,5 @@ oscarJDBC8 test - - ${project.groupId} - json-common-core - ${project.version} - diff --git a/saga/pom.xml b/saga/pom.xml index a5919647bf4..37376d671e9 100644 --- a/saga/pom.xml +++ b/saga/pom.xml @@ -48,12 +48,6 @@ ${project.version} - - ${project.groupId} - json-common-core - ${project.version} - - com.alibaba fastjson diff --git a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParser.java b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParser.java index ccc2342ef48..6b390b83120 100644 --- a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParser.java +++ b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParser.java @@ -19,7 +19,7 @@ /** * Json Parser * - * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonSerializer} in seata-common module instead. */ @Deprecated public interface JsonParser { diff --git a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParserFactory.java b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParserFactory.java index a8b4ab9e493..c4b4bd97476 100644 --- a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParserFactory.java +++ b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/JsonParserFactory.java @@ -25,7 +25,7 @@ /** * JsonParserFactory * - * @deprecated use {@link org.apache.seata.common.json.JsonSerializerFactory} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.JsonSerializerFactory} in seata-common module instead. */ @Deprecated public class JsonParserFactory { diff --git a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/FastjsonParser.java b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/FastjsonParser.java index 851e4d1bd69..ad49e4462df 100644 --- a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/FastjsonParser.java +++ b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/FastjsonParser.java @@ -25,7 +25,7 @@ /** * JsonParser implement by Fastjson * - * @deprecated use {@link org.apache.seata.common.json.impl.FastjsonJsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.impl.FastjsonJsonSerializer} in seata-common module instead. */ @Deprecated @LoadLevel(name = FastjsonParser.NAME) diff --git a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/JacksonJsonParser.java b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/JacksonJsonParser.java index f79abf45669..4e4a238ba16 100644 --- a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/JacksonJsonParser.java +++ b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/parser/impl/JacksonJsonParser.java @@ -32,7 +32,7 @@ /** * JsonParser implement by Jackson * - * @deprecated use {@link org.apache.seata.common.json.impl.JacksonJsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.impl.JacksonJsonSerializer} in seata-common module instead. */ @Deprecated @LoadLevel(name = JacksonJsonParser.NAME) diff --git a/server/pom.xml b/server/pom.xml index 9de1f407868..31287410998 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -486,7 +486,7 @@ ${project.groupId} - seata-threadpool-loom + seata-spi-jdk21 ${project.version} diff --git a/json-common/json-common-jackson3/pom.xml b/spi-jdk17/pom.xml similarity index 86% rename from json-common/json-common-jackson3/pom.xml rename to spi-jdk17/pom.xml index da4d5c48329..64c520ef5a7 100644 --- a/json-common/json-common-jackson3/pom.xml +++ b/spi-jdk17/pom.xml @@ -22,14 +22,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> org.apache.seata - json-common + seata-parent ${revision} 4.0.0 - json-common-jackson3 + seata-spi-jdk17 jar - json-common-jackson3 ${project.version} - Jackson 3 JSON serializer for Seata (requires JDK 17+) + seata-spi-jdk17 ${project.version} + JDK 17+ SPI extensions for Seata (Jackson 3 JSON serializer) 17 @@ -40,7 +40,7 @@ ${project.groupId} - json-common-core + seata-common ${project.version} diff --git a/json-common/json-common-jackson3/src/main/java/org/apache/seata/common/json/impl/Jackson3JsonSerializer.java b/spi-jdk17/src/main/java/org/apache/seata/common/json/impl/Jackson3JsonSerializer.java similarity index 100% rename from json-common/json-common-jackson3/src/main/java/org/apache/seata/common/json/impl/Jackson3JsonSerializer.java rename to spi-jdk17/src/main/java/org/apache/seata/common/json/impl/Jackson3JsonSerializer.java diff --git a/json-common/json-common-jackson3/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer b/spi-jdk17/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer similarity index 100% rename from json-common/json-common-jackson3/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer rename to spi-jdk17/src/main/resources/META-INF/services/org.apache.seata.common.json.JsonSerializer diff --git a/json-common/json-common-jackson3/src/test/java/org/apache/seata/common/json/Jackson3AllowlistTest.java b/spi-jdk17/src/test/java/org/apache/seata/common/json/Jackson3AllowlistTest.java similarity index 100% rename from json-common/json-common-jackson3/src/test/java/org/apache/seata/common/json/Jackson3AllowlistTest.java rename to spi-jdk17/src/test/java/org/apache/seata/common/json/Jackson3AllowlistTest.java diff --git a/json-common/json-common-jackson3/src/test/java/org/apache/seata/common/json/Jackson3JsonSerializerTest.java b/spi-jdk17/src/test/java/org/apache/seata/common/json/Jackson3JsonSerializerTest.java similarity index 100% rename from json-common/json-common-jackson3/src/test/java/org/apache/seata/common/json/Jackson3JsonSerializerTest.java rename to spi-jdk17/src/test/java/org/apache/seata/common/json/Jackson3JsonSerializerTest.java diff --git a/threadpool/pom.xml b/spi-jdk21/pom.xml similarity index 79% rename from threadpool/pom.xml rename to spi-jdk21/pom.xml index e0ec17f0e49..5618cb320da 100644 --- a/threadpool/pom.xml +++ b/spi-jdk21/pom.xml @@ -26,10 +26,15 @@ ${revision} 4.0.0 - seata-threadpool + seata-spi-jdk21 jar - seata-threadpool ${project.version} - Managed thread pool factory for Seata + seata-spi-jdk21 ${project.version} + JDK 21+ SPI extensions for Seata (virtual thread pool provider) + + + 21 + 21 + @@ -39,8 +44,9 @@ org.apache.seata - seata-config-core + seata-core ${project.version} + test diff --git a/threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualScheduledThreadPoolExecutor.java b/spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualScheduledThreadPoolExecutor.java similarity index 100% rename from threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualScheduledThreadPoolExecutor.java rename to spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualScheduledThreadPoolExecutor.java diff --git a/threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadFactoryHelper.java b/spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadFactoryHelper.java similarity index 100% rename from threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadFactoryHelper.java rename to spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadFactoryHelper.java diff --git a/threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolExecutor.java b/spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolExecutor.java similarity index 100% rename from threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolExecutor.java rename to spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolExecutor.java diff --git a/threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolProvider.java b/spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolProvider.java similarity index 100% rename from threadpool-loom/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolProvider.java rename to spi-jdk21/src/main/java/org/apache/seata/common/thread/VirtualThreadPoolProvider.java diff --git a/threadpool-loom/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider b/spi-jdk21/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider similarity index 100% rename from threadpool-loom/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider rename to spi-jdk21/src/main/resources/META-INF/services/org.apache.seata.common.thread.ThreadPoolProvider diff --git a/threadpool-loom/src/test/java/org/apache/seata/common/thread/VirtualThreadPoolProviderTest.java b/spi-jdk21/src/test/java/org/apache/seata/common/thread/VirtualThreadPoolProviderTest.java similarity index 100% rename from threadpool-loom/src/test/java/org/apache/seata/common/thread/VirtualThreadPoolProviderTest.java rename to spi-jdk21/src/test/java/org/apache/seata/common/thread/VirtualThreadPoolProviderTest.java diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-client/pom.xml b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-client/pom.xml index f0c5fb6fa3c..998d81f144f 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-client/pom.xml +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-client/pom.xml @@ -37,11 +37,6 @@ seata-spring-autoconfigure-core ${project.version} - - org.apache.seata - json-common-core - ${project.version} - javax.annotation javax.annotation-api diff --git a/tcc/src/main/java/org/apache/seata/rm/tcc/json/FastJsonParser.java b/tcc/src/main/java/org/apache/seata/rm/tcc/json/FastJsonParser.java index 120e986f360..11442b86b06 100644 --- a/tcc/src/main/java/org/apache/seata/rm/tcc/json/FastJsonParser.java +++ b/tcc/src/main/java/org/apache/seata/rm/tcc/json/FastJsonParser.java @@ -22,7 +22,7 @@ import org.apache.seata.integration.tx.api.json.JsonParser; /** - * @deprecated use {@link org.apache.seata.common.json.impl.FastjsonJsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.impl.FastjsonJsonSerializer} in seata-common module instead. */ @Deprecated @LoadLevel(name = Constants.FASTJSON_JSON_PARSER_NAME) diff --git a/tcc/src/main/java/org/apache/seata/rm/tcc/json/GsonJsonParser.java b/tcc/src/main/java/org/apache/seata/rm/tcc/json/GsonJsonParser.java index 26caf1e678e..efe27b3f902 100644 --- a/tcc/src/main/java/org/apache/seata/rm/tcc/json/GsonJsonParser.java +++ b/tcc/src/main/java/org/apache/seata/rm/tcc/json/GsonJsonParser.java @@ -25,7 +25,7 @@ import java.lang.reflect.Modifier; /** - * @deprecated use {@link org.apache.seata.common.json.impl.GsonJsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.impl.GsonJsonSerializer} in seata-common module instead. */ @Deprecated @LoadLevel(name = Constants.GSON_JSON_PARSER_NAME) diff --git a/tcc/src/main/java/org/apache/seata/rm/tcc/json/JacksonJsonParser.java b/tcc/src/main/java/org/apache/seata/rm/tcc/json/JacksonJsonParser.java index ea33594c244..a51f9cff88b 100644 --- a/tcc/src/main/java/org/apache/seata/rm/tcc/json/JacksonJsonParser.java +++ b/tcc/src/main/java/org/apache/seata/rm/tcc/json/JacksonJsonParser.java @@ -28,7 +28,7 @@ import java.io.IOException; /** - * @deprecated use {@link org.apache.seata.common.json.impl.JacksonJsonSerializer} in json-common-core module instead. + * @deprecated use {@link org.apache.seata.common.json.impl.JacksonJsonSerializer} in seata-common module instead. */ @Deprecated @LoadLevel(name = Constants.JACKSON_JSON_PARSER_NAME) diff --git a/threadpool-loom/pom.xml b/threadpool-loom/pom.xml deleted file mode 100644 index 1717daf07dd..00000000000 --- a/threadpool-loom/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - org.apache.seata - seata-parent - ${revision} - - 4.0.0 - seata-threadpool-loom - jar - seata-threadpool-loom ${project.version} - Loom-backed thread pool provider for Seata managed thread pools - - - 21 - 21 - - - - - org.apache.seata - seata-threadpool - ${project.version} - - -