diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7d9a4ea3dc7..c8ac1eaf267 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -79,7 +79,7 @@ jobs:
# step 4
- name: "Test with Maven"
run: |
- ./mvnw -T 4C clean test -Dspring-boot.version=${{ matrix.springboot }} -Dcheckstyle.skip=false -Dlicense.skip=false -e -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
+ ./mvnw -T 4C clean test -Dspring-boot.version=${{ matrix.springboot }} -Dcheckstyle.skip=true -Dlicense.skip=true -e -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
# job 3
arm64-test:
diff --git a/.licenserc.yaml b/.licenserc.yaml
index 699f39beee0..d295560cf1f 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -75,6 +75,7 @@ header:
- 'ext/apm-seata-skywalking-plugin/config/agent.config'
- 'server/src/main/resources/lua/redislocker/redislock.lua'
- 'server/src/main/resources/banner.txt'
+ - '**/org/springframework/**'
comment: on-failure
diff --git a/all/pom.xml b/all/pom.xml
index e0215683f9e..0bf311f1700 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -212,6 +212,16 @@
+
+ io.seata
+ seata-spring-aot-core
+ ${project.version}
+
+
+ io.seata
+ seata-spring-aot-client
+ ${project.version}
+
io.seata
seata-tcc
@@ -421,10 +431,6 @@
edas-sdk
provided
-
- net.bytebuddy
- byte-buddy
-
aopalliance
aopalliance
@@ -623,6 +629,13 @@
org.apache.maven.plugins
maven-shade-plugin
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
package
@@ -641,17 +654,17 @@
-
+
-
+
META-INF/spring.handlers
-
+
META-INF/spring.schemas
+
+ META-INF/spring/aot.factories
+
diff --git a/build/pom.xml b/build/pom.xml
index 53aca9c1e3d..2e60d208149 100644
--- a/build/pom.xml
+++ b/build/pom.xml
@@ -103,7 +103,7 @@
2.2.1
3.2.0
3.2.2
- 2.4.3
+ 3.2.4
3.0.2
3.0.0
3.2.0
diff --git a/changes/en-us/develop.md b/changes/en-us/develop.md
index ac4e8e9a02b..de23e996af3 100644
--- a/changes/en-us/develop.md
+++ b/changes/en-us/develop.md
@@ -3,7 +3,7 @@ Add changes here for all PR submitted to the develop branch.
### feature:
-- [[#xxx](https://github.com/seata/seata/pull/xxx)] support xxx
+- [[#5476](https://github.com/seata/seata/pull/5476)] First support `native-image` for `seata-client`
### bugfix:
- [[#5682](https://github.com/seata/seata/pull/5682)] fix saga mode replay context lost startParams
diff --git a/changes/zh-cn/develop.md b/changes/zh-cn/develop.md
index 4089687860b..98377d40790 100644
--- a/changes/zh-cn/develop.md
+++ b/changes/zh-cn/develop.md
@@ -3,7 +3,7 @@
### feature:
-- [[#xxx](https://github.com/seata/seata/pull/xxx)] 支持 xxx
+- [[#5476](https://github.com/seata/seata/pull/5476)] seata客户端,首次支持 `native-image`
### bugfix:
- [[#5682](https://github.com/seata/seata/pull/5682)] 修复saga模式下replay context丢失startParams问题
diff --git a/common/src/main/java/io/seata/common/aot/NativeUtils.java b/common/src/main/java/io/seata/common/aot/NativeUtils.java
new file mode 100644
index 00000000000..e708d9a78a5
--- /dev/null
+++ b/common/src/main/java/io/seata/common/aot/NativeUtils.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed 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 io.seata.common.aot;
+
+/**
+ * The native utils
+ *
+ * @author wang.liang
+ */
+public class NativeUtils {
+
+ /**
+ * The native-image code
+ *
+ * @see ImageInfo.java
+ */
+ private static final String NATIVE_IMAGE_CODE = System.getProperty("org.graalvm.nativeimage.imagecode");
+
+
+ public static final String SPRING_AOT_PROCESSING = "spring.aot.processing";
+
+
+ /**
+ * Whether Spring-AOT processing
+ *
+ * @return the boolean
+ */
+ public static boolean isSpringAotProcessing() {
+ return "true".equalsIgnoreCase(System.getProperty(SPRING_AOT_PROCESSING));
+ }
+
+ /**
+ * Gets the native-image code.
+ *
+ * @return the native-image code
+ */
+ public static String getNativeImageCode() {
+ return NATIVE_IMAGE_CODE;
+ }
+
+ /**
+ * Whether run in native-image
+ *
+ * @return the boolean
+ * @see org.springframework.core.NativeDetector#inNativeImage()
+ */
+ public static boolean inNativeImage() {
+ return NATIVE_IMAGE_CODE != null;
+ }
+}
diff --git a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
index dc56d50f76c..69f7189a099 100644
--- a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
+++ b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
@@ -44,6 +44,9 @@
*/
public class EnhancedServiceLoader {
+ public static final String SERVICES_DIRECTORY = "META-INF/services/";
+ public static final String SEATA_DIRECTORY = "META-INF/seata/";
+
/**
* Class->InnerEnhancedServiceLoader map
*/
@@ -245,8 +248,6 @@ private static ClassLoader findClassLoader() {
private static class InnerEnhancedServiceLoader {
private static final Logger LOGGER = LoggerFactory.getLogger(InnerEnhancedServiceLoader.class);
- private static final String SERVICES_DIRECTORY = "META-INF/services/";
- private static final String SEATA_DIRECTORY = "META-INF/seata/";
private final Class type;
private final Holder>> definitionsHolder = new Holder<>();
@@ -555,7 +556,9 @@ private void loadFile(String dir, ClassLoader loader, List getWrappedClass(Class> clazz) {
return clazz;
}
+ public static boolean isJavaClass(Class> clazz) {
+ return clazz != null && clazz.getClassLoader() == null;
+ }
+
+ /**
+ * Whether the class exists
+ *
+ * @param className the class name
+ * @return the boolean
+ */
+ public static boolean existsClass(String className) {
+ try {
+ getClassByName(className);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
//endregion
diff --git a/common/src/main/resources/META-INF/native-image/io.seata/seata-common/resource-config.json b/common/src/main/resources/META-INF/native-image/io.seata/seata-common/resource-config.json
new file mode 100644
index 00000000000..a8a21ce022d
--- /dev/null
+++ b/common/src/main/resources/META-INF/native-image/io.seata/seata-common/resource-config.json
@@ -0,0 +1,66 @@
+{
+ "resources": {
+ "includes": [
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/services\/io.seata.\\E.*"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/seata\/io.seata.\\E.*"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/services\/com.alibaba.dubbo.rpc.Filter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/seata\/com.alibaba.dubbo.rpc.Filter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/services\/com.alipay.sofa.rpc.filter.Filter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/seata\/com.alipay.sofa.rpc.filter.Filter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/services\/com.taobao.hsf.invocation.filter.RPCFilter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/seata\/com.taobao.hsf.invocation.filter.RPCFilter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/services\/com.weibo.api.motan.filter.Filter\\E"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.EnhancedServiceLoader"
+ },
+ "pattern": "\\QMETA-INF\/seata\/com.weibo.api.motan.filter.Filter\\E"
+ }
+ ]
+ }
+}
diff --git a/common/src/test/resources/META-INF/native-image/io.seata/seata-common/reflect-config.json b/common/src/test/resources/META-INF/native-image/io.seata/seata-common/reflect-config.json
new file mode 100644
index 00000000000..1dc92069584
--- /dev/null
+++ b/common/src/test/resources/META-INF/native-image/io.seata/seata-common/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.Hello"
+ },
+ "name": "io.seata.common.loader.ChineseHello",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-7z/src/main/resources/META-INF/native-image/io.seata/seata-compressor-7z/reflect-config.json b/compressor/seata-compressor-7z/src/main/resources/META-INF/native-image/io.seata/seata-compressor-7z/reflect-config.json
new file mode 100644
index 00000000000..b49e8b6c200
--- /dev/null
+++ b/compressor/seata-compressor-7z/src/main/resources/META-INF/native-image/io.seata/seata-compressor-7z/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.sevenz.SevenZCompressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-bzip2/src/main/resources/META-INF/native-image/io.seata/seata-compressor-bzip2/reflect-config.json b/compressor/seata-compressor-bzip2/src/main/resources/META-INF/native-image/io.seata/seata-compressor-bzip2/reflect-config.json
new file mode 100644
index 00000000000..f5db3d44afc
--- /dev/null
+++ b/compressor/seata-compressor-bzip2/src/main/resources/META-INF/native-image/io.seata/seata-compressor-bzip2/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.bzip2.BZip2Compressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-deflater/src/main/resources/META-INF/native-image/io.seata/seata-compressor-deflater/reflect-config.json b/compressor/seata-compressor-deflater/src/main/resources/META-INF/native-image/io.seata/seata-compressor-deflater/reflect-config.json
new file mode 100644
index 00000000000..82cae57a764
--- /dev/null
+++ b/compressor/seata-compressor-deflater/src/main/resources/META-INF/native-image/io.seata/seata-compressor-deflater/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.deflater.DeflaterCompressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-gzip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-gzip/reflect-config.json b/compressor/seata-compressor-gzip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-gzip/reflect-config.json
new file mode 100644
index 00000000000..e86eb53c3e1
--- /dev/null
+++ b/compressor/seata-compressor-gzip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-gzip/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.gzip.GzipCompressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-lz4/src/main/resources/META-INF/native-image/io.seata/seata-compressor-lz4/reflect-config.json b/compressor/seata-compressor-lz4/src/main/resources/META-INF/native-image/io.seata/seata-compressor-lz4/reflect-config.json
new file mode 100644
index 00000000000..a0303f660de
--- /dev/null
+++ b/compressor/seata-compressor-lz4/src/main/resources/META-INF/native-image/io.seata/seata-compressor-lz4/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.lz4.Lz4Compressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-zip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zip/reflect-config.json b/compressor/seata-compressor-zip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zip/reflect-config.json
new file mode 100644
index 00000000000..8e052e52bdb
--- /dev/null
+++ b/compressor/seata-compressor-zip/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zip/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.zip.ZipCompressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/compressor/seata-compressor-zstd/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zstd/reflect-config.json b/compressor/seata-compressor-zstd/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zstd/reflect-config.json
new file mode 100644
index 00000000000..772676f43fe
--- /dev/null
+++ b/compressor/seata-compressor-zstd/src/main/resources/META-INF/native-image/io.seata/seata-compressor-zstd/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.compressor.Compressor"
+ },
+ "name": "io.seata.compressor.zstd.ZstdCompressor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-apollo/src/main/resources/META-INF/native-image/io.seata/seata-config-apollo/reflect-config.json b/config/seata-config-apollo/src/main/resources/META-INF/native-image/io.seata/seata-config-apollo/reflect-config.json
new file mode 100644
index 00000000000..d5dad7e68db
--- /dev/null
+++ b/config/seata-config-apollo/src/main/resources/META-INF/native-image/io.seata/seata-config-apollo/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.apollo.ApolloConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-consul/src/main/resources/META-INF/native-image/io.seata/seata-config-consul/reflect-config.json b/config/seata-config-consul/src/main/resources/META-INF/native-image/io.seata/seata-config-consul/reflect-config.json
new file mode 100644
index 00000000000..575a55ecc9e
--- /dev/null
+++ b/config/seata-config-consul/src/main/resources/META-INF/native-image/io.seata/seata-config-consul/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.consul.ConsulConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-core/pom.xml b/config/seata-config-core/pom.xml
index 72098b12471..f167cca61e2 100644
--- a/config/seata-config-core/pom.xml
+++ b/config/seata-config-core/pom.xml
@@ -40,10 +40,6 @@
org.yaml
snakeyaml
-
- net.bytebuddy
- byte-buddy
-
diff --git a/config/seata-config-core/src/main/java/io/seata/config/ConfigurationCache.java b/config/seata-config-core/src/main/java/io/seata/config/ConfigurationCache.java
index e837ce78fae..f3e6bd6c224 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/ConfigurationCache.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/ConfigurationCache.java
@@ -15,17 +15,16 @@
*/
package io.seata.config;
+import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
+
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.DurationUtil;
import io.seata.common.util.StringUtils;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.implementation.InvocationHandlerAdapter;
-import net.bytebuddy.matcher.ElementMatchers;
/**
* @author funkye
@@ -101,8 +100,8 @@ public void onChangeEvent(ConfigurationChangeEvent event) {
}
public Configuration proxy(Configuration originalConfiguration) throws Exception {
- return new ByteBuddy().subclass(Configuration.class).method(ElementMatchers.any())
- .intercept(InvocationHandlerAdapter.of((proxy, method, args) -> {
+ return (Configuration)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Configuration.class}
+ , (proxy, method, args) -> {
String methodName = method.getName();
if (methodName.startsWith(METHOD_PREFIX) && !methodName.equalsIgnoreCase(METHOD_LATEST_CONFIG)) {
String rawDataId = (String)args[0];
@@ -126,8 +125,8 @@ public Configuration proxy(Configuration originalConfiguration) throws Exception
return wrapper == null ? null : wrapper.convertData(type);
}
return method.invoke(originalConfiguration, args);
- })).make().load(originalConfiguration.getClass().getClassLoader()).getLoaded().getDeclaredConstructor()
- .newInstance();
+ }
+ );
}
private static class ConfigurationCacheInstance {
diff --git a/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/proxy-config.json b/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/proxy-config.json
new file mode 100644
index 00000000000..e46ef9962f0
--- /dev/null
+++ b/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/proxy-config.json
@@ -0,0 +1,10 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationCache"
+ },
+ "interfaces": [
+ "io.seata.config.Configuration"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/reflect-config.json b/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/reflect-config.json
new file mode 100644
index 00000000000..361153750e9
--- /dev/null
+++ b/config/seata-config-core/src/main/resources/META-INF/native-image/io.seata/seata-config-core/reflect-config.json
@@ -0,0 +1,56 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.file.FileConfig"
+ },
+ "name": "io.seata.config.file.SimpleFileConfig",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.io.File",
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.file.FileConfig"
+ },
+ "name": "io.seata.config.file.YamlFileConfig",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.io.File",
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.processor.Processor"
+ },
+ "name": "io.seata.config.processor.ProcessorProperties",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.processor.Processor"
+ },
+ "name": "io.seata.config.processor.ProcessorYaml",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-core/src/main/resources/META-INF/services/io.seata.config.file.FileConfig b/config/seata-config-core/src/main/resources/META-INF/services/io.seata.config.file.FileConfig
index 911c3d91a46..b44f1b5ce05 100644
--- a/config/seata-config-core/src/main/resources/META-INF/services/io.seata.config.file.FileConfig
+++ b/config/seata-config-core/src/main/resources/META-INF/services/io.seata.config.file.FileConfig
@@ -1,2 +1,2 @@
io.seata.config.file.SimpleFileConfig
-io.seata.config.file.YamlFileConfig
+io.seata.config.file.YamlFileConfig
\ No newline at end of file
diff --git a/config/seata-config-custom/src/main/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json b/config/seata-config-custom/src/main/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json
new file mode 100644
index 00000000000..9cece512be6
--- /dev/null
+++ b/config/seata-config-custom/src/main/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.custom.CustomConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-custom/src/test/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json b/config/seata-config-custom/src/test/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json
new file mode 100644
index 00000000000..babebe2a8f3
--- /dev/null
+++ b/config/seata-config-custom/src/test/resources/META-INF/native-image/io.seata/seata-config-custom/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.CustomConfigurationProviderForTest",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-config-etcd3/reflect-config.json b/config/seata-config-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-config-etcd3/reflect-config.json
new file mode 100644
index 00000000000..00da19d813a
--- /dev/null
+++ b/config/seata-config-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-config-etcd3/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.etcd3.EtcdConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-nacos/src/main/resources/META-INF/native-image/io.seata/seata-config-nacos/reflect-config.json b/config/seata-config-nacos/src/main/resources/META-INF/native-image/io.seata/seata-config-nacos/reflect-config.json
new file mode 100644
index 00000000000..c8ed1707fce
--- /dev/null
+++ b/config/seata-config-nacos/src/main/resources/META-INF/native-image/io.seata/seata-config-nacos/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.nacos.NacosConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-spring-cloud/src/main/resources/META-INF/native-image/io.seata/seata-config-spring-cloud/reflect-config.json b/config/seata-config-spring-cloud/src/main/resources/META-INF/native-image/io.seata/seata-config-spring-cloud/reflect-config.json
new file mode 100644
index 00000000000..05f33a9d39b
--- /dev/null
+++ b/config/seata-config-spring-cloud/src/main/resources/META-INF/native-image/io.seata/seata-config-spring-cloud/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.springcloud.SpringCloudConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/config/seata-config-zk/src/main/resources/META-INF/native-image/io.seata/seata-config-zk/reflect-config.json b/config/seata-config-zk/src/main/resources/META-INF/native-image/io.seata/seata-config-zk/reflect-config.json
new file mode 100644
index 00000000000..b3ed5b43182
--- /dev/null
+++ b/config/seata-config-zk/src/main/resources/META-INF/native-image/io.seata/seata-config-zk/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ConfigurationProvider"
+ },
+ "name": "io.seata.config.zk.ZookeeperConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/console/src/main/resources/META-INF/native-image/io.seata/seata-console/resource-config.json b/console/src/main/resources/META-INF/native-image/io.seata/seata-console/resource-config.json
new file mode 100644
index 00000000000..2128dbb992b
--- /dev/null
+++ b/console/src/main/resources/META-INF/native-image/io.seata/seata-console/resource-config.json
@@ -0,0 +1,9 @@
+{
+ "resources": {
+ "includes": [
+ {
+ "pattern": "\\Qstatic\/\\E.*"
+ }
+ ]
+ }
+}
diff --git a/core/src/main/resources/META-INF/native-image/io.seata/seata-core/reflect-config.json b/core/src/main/resources/META-INF/native-image/io.seata/seata-core/reflect-config.json
new file mode 100644
index 00000000000..ec2f79715c4
--- /dev/null
+++ b/core/src/main/resources/META-INF/native-image/io.seata/seata-core/reflect-config.json
@@ -0,0 +1,188 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.constants.DubboConstants"
+ },
+ "name": "org.apache.dubbo.rpc.RpcContext"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.SerializerServiceLoader"
+ },
+ "name": "io.seata.serializer.protobuf.ProtobufSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.auth.AuthSigner"
+ },
+ "name": "io.seata.core.auth.DefaultAuthSigner",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.context.ContextCore"
+ },
+ "name": "io.seata.core.context.ThreadLocalContextCore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.context.ContextCore"
+ },
+ "name": "io.seata.core.context.FastThreadLocalContextCore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.rpc.hook.RpcHook"
+ },
+ "name": "io.seata.core.rpc.hook.StatusRpcHook",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.lock.LockStoreSql"
+ },
+ "name": "io.seata.core.store.db.sql.lock.MysqlLockStoreSql",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.lock.LockStoreSql"
+ },
+ "name": "io.seata.core.store.db.sql.lock.OracleLockStoreSql",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.lock.LockStoreSql"
+ },
+ "name": "io.seata.core.store.db.sql.lock.OceanbaseLockStoreSql",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.lock.LockStoreSql"
+ },
+ "name": "io.seata.core.store.db.sql.lock.PostgresqlLockStoreSql",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.lock.LockStoreSql"
+ },
+ "name": "io.seata.core.store.db.sql.lock.H2LockStoreSql",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.log.LogStoreSqls"
+ },
+ "name": "io.seata.core.store.db.sql.log.MysqlLogStoreSqls",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.log.LogStoreSqls"
+ },
+ "name": "io.seata.core.store.db.sql.log.OracleLogStoreSqls",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.log.LogStoreSqls"
+ },
+ "name": "io.seata.core.store.db.sql.log.PostgresqlLogStoreSqls",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.log.LogStoreSqls"
+ },
+ "name": "io.seata.core.store.db.sql.log.OceanbaseLogStoreSqls",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.sql.log.LogStoreSqls"
+ },
+ "name": "io.seata.core.store.db.sql.log.H2LogStoreSqls",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-consul/src/main/resources/META-INF/native-image/io.seata/seata-discovery-consul/reflect-config.json b/discovery/seata-discovery-consul/src/main/resources/META-INF/native-image/io.seata/seata-discovery-consul/reflect-config.json
new file mode 100644
index 00000000000..301a05860e6
--- /dev/null
+++ b/discovery/seata-discovery-consul/src/main/resources/META-INF/native-image/io.seata/seata-discovery-consul/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.consul.ConsulRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-core/src/main/resources/META-INF/native-image/io.seata/seata-discovery-core/reflect-config.json b/discovery/seata-discovery-core/src/main/resources/META-INF/native-image/io.seata/seata-discovery-core/reflect-config.json
new file mode 100644
index 00000000000..1a99d36dc36
--- /dev/null
+++ b/discovery/seata-discovery-core/src/main/resources/META-INF/native-image/io.seata/seata-discovery-core/reflect-config.json
@@ -0,0 +1,74 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.loadbalance.LoadBalance"
+ },
+ "name": "io.seata.discovery.loadbalance.RoundRobinLoadBalance",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.loadbalance.LoadBalance"
+ },
+ "name": "io.seata.discovery.loadbalance.RandomLoadBalance",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.loadbalance.LoadBalance"
+ },
+ "name": "io.seata.discovery.loadbalance.ConsistentHashLoadBalance",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.loadbalance.LoadBalance"
+ },
+ "name": "io.seata.discovery.loadbalance.LeastActiveLoadBalance",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.loadbalance.LoadBalance"
+ },
+ "name": "io.seata.discovery.loadbalance.XIDLoadBalance",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.FileRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-custom/src/main/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json b/discovery/seata-discovery-custom/src/main/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json
new file mode 100644
index 00000000000..a5116bcf110
--- /dev/null
+++ b/discovery/seata-discovery-custom/src/main/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.custom.CustomRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-custom/src/test/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json b/discovery/seata-discovery-custom/src/test/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json
new file mode 100644
index 00000000000..db8a46ecfdf
--- /dev/null
+++ b/discovery/seata-discovery-custom/src/test/resources/META-INF/native-image/io.seata/seata-discovery-custom/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.custom.CustomRegistryProviderForTest",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-discovery-etcd3/reflect-config.json b/discovery/seata-discovery-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-discovery-etcd3/reflect-config.json
new file mode 100644
index 00000000000..ad34373e0fd
--- /dev/null
+++ b/discovery/seata-discovery-etcd3/src/main/resources/META-INF/native-image/io.seata/seata-discovery-etcd3/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.etcd3.EtcdRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-eureka/src/main/resources/META-INF/native-image/io.seata/seata-discovery-eureka/reflect-config.json b/discovery/seata-discovery-eureka/src/main/resources/META-INF/native-image/io.seata/seata-discovery-eureka/reflect-config.json
new file mode 100644
index 00000000000..a9a50eaa8ec
--- /dev/null
+++ b/discovery/seata-discovery-eureka/src/main/resources/META-INF/native-image/io.seata/seata-discovery-eureka/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.eureka.EurekaRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-nacos/src/main/resources/META-INF/native-image/io.seata/seata-discovery-nacos/reflect-config.json b/discovery/seata-discovery-nacos/src/main/resources/META-INF/native-image/io.seata/seata-discovery-nacos/reflect-config.json
new file mode 100644
index 00000000000..391c28cdfe9
--- /dev/null
+++ b/discovery/seata-discovery-nacos/src/main/resources/META-INF/native-image/io.seata/seata-discovery-nacos/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.nacos.NacosRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-redis/src/main/resources/META-INF/native-image/io.seata/seata-discovery-redis/reflect-config.json b/discovery/seata-discovery-redis/src/main/resources/META-INF/native-image/io.seata/seata-discovery-redis/reflect-config.json
new file mode 100644
index 00000000000..fc26abafdff
--- /dev/null
+++ b/discovery/seata-discovery-redis/src/main/resources/META-INF/native-image/io.seata/seata-discovery-redis/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.redis.RedisRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-sofa/src/main/resources/META-INF/native-image/io.seata/seata-discovery-sofa/reflect-config.json b/discovery/seata-discovery-sofa/src/main/resources/META-INF/native-image/io.seata/seata-discovery-sofa/reflect-config.json
new file mode 100644
index 00000000000..2e7bb3c74a5
--- /dev/null
+++ b/discovery/seata-discovery-sofa/src/main/resources/META-INF/native-image/io.seata/seata-discovery-sofa/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.sofa.SofaRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/discovery/seata-discovery-zk/src/main/resources/META-INF/native-image/io.seata/seata-discovery-zk/reflect-config.json b/discovery/seata-discovery-zk/src/main/resources/META-INF/native-image/io.seata/seata-discovery-zk/reflect-config.json
new file mode 100644
index 00000000000..301262c3441
--- /dev/null
+++ b/discovery/seata-discovery-zk/src/main/resources/META-INF/native-image/io.seata/seata-discovery-zk/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.discovery.registry.RegistryProvider"
+ },
+ "name": "io.seata.discovery.registry.zk.ZookeeperRegistryProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/integration/dubbo-alibaba/src/main/resources/META-INF/native-image/io.seata/seata-dubbo-alibaba/reflect-config.json b/integration/dubbo-alibaba/src/main/resources/META-INF/native-image/io.seata/seata-dubbo-alibaba/reflect-config.json
new file mode 100644
index 00000000000..3aabc896ced
--- /dev/null
+++ b/integration/dubbo-alibaba/src/main/resources/META-INF/native-image/io.seata/seata-dubbo-alibaba/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.dubbo.rpc.Filter"
+ },
+ "name": "io.seata.integration.dubbo.alibaba.AlibabaDubboTransactionPropagationFilter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/integration/hsf/src/main/resources/META-INF/native-image/io.seata/seata-hsf/reflect-config.json b/integration/hsf/src/main/resources/META-INF/native-image/io.seata/seata-hsf/reflect-config.json
new file mode 100644
index 00000000000..ec2ca59dbd1
--- /dev/null
+++ b/integration/hsf/src/main/resources/META-INF/native-image/io.seata/seata-hsf/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "com.taobao.hsf.invocation.filter.RPCFilter"
+ },
+ "name": "io.seata.integration.hsf.HsfTransactionFilter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/integration/motan/src/main/resources/META-INF/native-image/io.seata/seata-motan/reflect-config.json b/integration/motan/src/main/resources/META-INF/native-image/io.seata/seata-motan/reflect-config.json
new file mode 100644
index 00000000000..20fc9d92636
--- /dev/null
+++ b/integration/motan/src/main/resources/META-INF/native-image/io.seata/seata-motan/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "com.weibo.api.motan.filter.Filter"
+ },
+ "name": "io.seata.integration.motan.MotanTransactionFilter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/integration/sofa-rpc/src/main/resources/META-INF/native-image/io.seata/seata-sofa-rpc/reflect-config.json b/integration/sofa-rpc/src/main/resources/META-INF/native-image/io.seata/seata-sofa-rpc/reflect-config.json
new file mode 100644
index 00000000000..21eab9bdc03
--- /dev/null
+++ b/integration/sofa-rpc/src/main/resources/META-INF/native-image/io.seata/seata-sofa-rpc/reflect-config.json
@@ -0,0 +1,26 @@
+[
+ {
+ "condition": {
+ "typeReachable": "com.alipay.sofa.rpc.filter.Filter"
+ },
+ "name": "io.seata.integration.sofa.rpc.TransactionContextProviderFilter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alipay.sofa.rpc.filter.Filter"
+ },
+ "name": "io.seata.integration.sofa.rpc.TransactionContextConsumerFilter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/native-image/io.seata/seata-metrics-exporter-prometheus/reflect-config.json b/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/native-image/io.seata/seata-metrics-exporter-prometheus/reflect-config.json
new file mode 100644
index 00000000000..2de446ee26e
--- /dev/null
+++ b/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/native-image/io.seata/seata-metrics-exporter-prometheus/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.metrics.exporter.Exporter"
+ },
+ "name": "io.seata.metrics.exporter.prometheus.PrometheusExporter",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/native-image/io.seata/seata-metrics-registry-compact/reflect-config.json b/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/native-image/io.seata/seata-metrics-registry-compact/reflect-config.json
new file mode 100644
index 00000000000..5f241d7a6cd
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/native-image/io.seata/seata-metrics-registry-compact/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.metrics.registry.Registry"
+ },
+ "name": "io.seata.metrics.registry.compact.CompactRegistry",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c60930ccad5..44071516399 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,8 @@
rm
rm-datasource
spring
+ spring-aot
+ spring-framework-fake-for-java8
tcc
test
tm
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/util/SeataXAResource.java b/rm-datasource/src/main/java/io/seata/rm/datasource/util/SeataXAResource.java
index 924fec80795..e185fb5477e 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/util/SeataXAResource.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/util/SeataXAResource.java
@@ -22,7 +22,8 @@
* @since 2023/3/16
*/
public interface SeataXAResource extends XAResource {
+
// OracleXAResource Loosely Coupled Branches
- public static final int ORATRANSLOOSE = 65536;
+ int ORATRANSLOOSE = 65536;
}
diff --git a/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/native-image.properties b/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/native-image.properties
new file mode 100644
index 00000000000..109df519963
--- /dev/null
+++ b/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/native-image.properties
@@ -0,0 +1,16 @@
+#
+# Copyright 1999-2019 Seata.io Group.
+#
+# Licensed 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.
+
+Args = -H:+AddAllCharsets
\ No newline at end of file
diff --git a/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json b/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json
new file mode 100644
index 00000000000..64dde84a0af
--- /dev/null
+++ b/rm-datasource/src/main/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json
@@ -0,0 +1,654 @@
+[
+ {
+ "condition": {
+ "typeReachable": "com.mysql.jdbc.Driver"
+ },
+ "name": "io.seata.rm.datasource.exec.mysql.MySQLInsertExecutor",
+ "allDeclaredConstructors": true
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.jdbc.Driver"
+ },
+ "name": "io.seata.rm.datasource.exec.mysql.MySQLInsertExecutor",
+ "allDeclaredConstructors": true
+ },
+ {
+ "condition": {
+ "typeReachable": "oracle.jdbc.driver.OracleDriver"
+ },
+ "name": "io.seata.rm.datasource.exec.oracle.OracleInsertExecutor",
+ "allDeclaredConstructors": true
+ },
+ {
+ "condition": {
+ "typeReachable": "org.postgresql.Driver"
+ },
+ "name": "io.seata.rm.datasource.exec.postgresql.PostgresqlInsertExecutor",
+ "allDeclaredConstructors": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.BranchUndoLog"
+ },
+ "name": "io.seata.rm.datasource.undo.BranchUndoLog",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.Row"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.Row",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.TableRecords"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.TableRecords",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.Field"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.Field",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.SQLUndoLog"
+ },
+ "name": "io.seata.rm.datasource.undo.SQLUndoLog",
+ "allPublicClasses": true,
+ "allPublicConstructors": true,
+ "allDeclaredConstructors": true,
+ "allDeclaredMethods": true,
+ "allDeclaredFields": true,
+ "allPublicMethods": true,
+ "allPublicFields": true,
+ "allDeclaredClasses": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.cache.AbstractTableMetaCache"
+ },
+ "name": "com.github.benmanes.caffeine.cache.SIMSW",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "com.github.benmanes.caffeine.cache.Caffeine",
+ "com.github.benmanes.caffeine.cache.AsyncCacheLoader",
+ "boolean"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.cache.AbstractTableMetaCache"
+ },
+ "name": "com.github.benmanes.caffeine.cache.PDWMS",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.util.XAUtils"
+ },
+ "name": "oracle.jdbc.driver.T4CXAConnection",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.sql.Connection"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.util.XAUtils"
+ },
+ "name": "oracle.jdbc.xa.client.OracleXAConnection",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.sql.Connection"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.jdbc.Util",
+ "methods": [
+ {
+ "name": "isJdbc4",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.jdbc.Connection",
+ "methods": [
+ {
+ "name": "getPinGlobalTxToPhysicalConnection",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "com.mysql.jdbc.Connection"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "com.mysql.jdbc.Connection"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.jdbc.jdbc2.optional.MysqlXAConnection",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "com.mysql.jdbc.Connection",
+ "boolean"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.cj.jdbc.JdbcConnection",
+ "methods": [
+ {
+ "name": "getPropertySet",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.jdbc.JdbcConnection"
+ },
+ "name": "com.mysql.cj.conf.PropertySet",
+ "methods": [
+ {
+ "name": "getBooleanReadableProperty",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.jdbc.JdbcConnection"
+ },
+ "name": "com.mysql.cj.conf.ReadableProperty",
+ "methods": [
+ {
+ "name": "getValue",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.jdbc.JdbcConnection"
+ },
+ "name": "com.mysql.cj.conf.RuntimeProperty",
+ "methods": [
+ {
+ "name": "getValue",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.cj.api.jdbc.JdbcConnection",
+ "methods": [
+ {
+ "name": "getPropertySet",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.api.jdbc.JdbcConnection"
+ },
+ "name": "com.mysql.cj.api.conf.PropertySet",
+ "methods": [
+ {
+ "name": "getBooleanReadableProperty",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.mysql.cj.api.jdbc.JdbcConnection"
+ },
+ "name": "com.mysql.cj.api.conf.ReadableProperty",
+ "methods": [
+ {
+ "name": "getValue",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.cj.jdbc.SuspendableXAConnection",
+ "methods": [
+ {
+ "name": "getInstance",
+ "parameterTypes": [
+ "com.mysql.cj.jdbc.JdbcConnection"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.alibaba.druid.util.MySqlUtils"
+ },
+ "name": "com.mysql.cj.jdbc.MysqlXAConnection",
+ "methods": [
+ {
+ "name": "getInstance",
+ "parameterTypes": [
+ "com.mysql.cj.jdbc.JdbcConnection",
+ "boolean"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.model.ResourceManager"
+ },
+ "name": "io.seata.rm.datasource.DataSourceManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.model.ResourceManager"
+ },
+ "name": "io.seata.rm.datasource.xa.ResourceManagerXA",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.AbstractRMHandler"
+ },
+ "name": "io.seata.rm.RMHandlerAT",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.AbstractRMHandler"
+ },
+ "name": "io.seata.rm.RMHandlerXA",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.exec.InsertExecutor"
+ },
+ "name": "io.seata.rm.datasource.exec.mysql.MySQLInsertExecutor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.rm.datasource.StatementProxy",
+ "io.seata.rm.datasource.exec.StatementCallback",
+ "io.seata.sqlparser.SQLRecognizer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.exec.InsertExecutor"
+ },
+ "name": "io.seata.rm.datasource.exec.oracle.OracleInsertExecutor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.rm.datasource.StatementProxy",
+ "io.seata.rm.datasource.exec.StatementCallback",
+ "io.seata.sqlparser.SQLRecognizer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.exec.InsertExecutor"
+ },
+ "name": "io.seata.rm.datasource.exec.postgresql.PostgresqlInsertExecutor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.rm.datasource.StatementProxy",
+ "io.seata.rm.datasource.exec.StatementCallback",
+ "io.seata.sqlparser.SQLRecognizer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.TableMetaCache"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.cache.MysqlTableMetaCache",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.TableMetaCache"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.cache.OracleTableMetaCache",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.sql.struct.TableMetaCache"
+ },
+ "name": "io.seata.rm.datasource.sql.struct.cache.PostgresqlTableMetaCache",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoExecutorHolder"
+ },
+ "name": "io.seata.rm.datasource.undo.mysql.MySQLUndoExecutorHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoExecutorHolder"
+ },
+ "name": "io.seata.rm.datasource.undo.oracle.OracleUndoExecutorHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoExecutorHolder"
+ },
+ "name": "io.seata.rm.datasource.undo.postgresql.PostgresqlUndoExecutorHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogManager"
+ },
+ "name": "io.seata.rm.datasource.undo.mysql.MySQLUndoLogManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogManager"
+ },
+ "name": "io.seata.rm.datasource.undo.oracle.OracleUndoLogManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogManager"
+ },
+ "name": "io.seata.rm.datasource.undo.postgresql.PostgresqlUndoLogManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogParser"
+ },
+ "name": "io.seata.rm.datasource.undo.parser.FastjsonUndoLogParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogParser"
+ },
+ "name": "io.seata.rm.datasource.undo.parser.JacksonUndoLogParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogParser"
+ },
+ "name": "io.seata.rm.datasource.undo.parser.ProtostuffUndoLogParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogParser"
+ },
+ "name": "io.seata.rm.datasource.undo.parser.KryoUndoLogParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.UndoLogParser"
+ },
+ "name": "io.seata.rm.datasource.undo.parser.FstUndoLogParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.KeywordChecker"
+ },
+ "name": "io.seata.rm.datasource.undo.oracle.keyword.OracleKeywordChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.KeywordChecker"
+ },
+ "name": "io.seata.rm.datasource.undo.mysql.keyword.MySQLKeywordChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.KeywordChecker"
+ },
+ "name": "io.seata.rm.datasource.undo.postgresql.keyword.PostgresqlKeywordChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/rm-datasource/src/test/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json b/rm-datasource/src/test/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json
new file mode 100644
index 00000000000..2e31117e9ce
--- /dev/null
+++ b/rm-datasource/src/test/resources/META-INF/native-image/io.seata/seata-rm-datasource/reflect-config.json
@@ -0,0 +1,74 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.mysql.MySQLOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.oracle.OracleOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.postgresql.PostgresqlOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.KeywordChecker"
+ },
+ "name": "io.seata.rm.datasource.undo.h2.keyword.H2KeywordChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.SQLRecognizerFactory"
+ },
+ "name": "io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.util.DbTypeParser"
+ },
+ "name": "io.seata.sqlparser.druid.DruidDelegatingDbTypeParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
index f4b2f829968..e360e22891c 100644
--- a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
+++ b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
@@ -1,17 +1 @@
-#
-# Copyright 1999-2019 Seata.io Group.
-#
-# Licensed 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.
-#
-
-io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory
+io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory
\ No newline at end of file
diff --git a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.druid.SQLOperateRecognizerHolder b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.druid.SQLOperateRecognizerHolder
index e7a870fdf31..0e290f5bd49 100644
--- a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.druid.SQLOperateRecognizerHolder
+++ b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.druid.SQLOperateRecognizerHolder
@@ -1,19 +1,3 @@
-#
-# Copyright 1999-2019 Seata.io Group.
-#
-# Licensed 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.
-#
-
io.seata.sqlparser.druid.mysql.MySQLOperateRecognizerHolder
io.seata.sqlparser.druid.oracle.OracleOperateRecognizerHolder
io.seata.sqlparser.druid.postgresql.PostgresqlOperateRecognizerHolder
\ No newline at end of file
diff --git a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
index 983f0c35c92..a1eca58fd2a 100644
--- a/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
+++ b/rm-datasource/src/test/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
@@ -1,17 +1 @@
-#
-# Copyright 1999-2019 Seata.io Group.
-#
-# Licensed 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.
-#
-
-io.seata.sqlparser.druid.DruidDelegatingDbTypeParser
+io.seata.sqlparser.druid.DruidDelegatingDbTypeParser
\ No newline at end of file
diff --git a/saga/seata-saga-engine-store/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine-store/reflect-config.json b/saga/seata-saga-engine-store/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine-store/reflect-config.json
new file mode 100644
index 00000000000..f9655b50f39
--- /dev/null
+++ b/saga/seata-saga-engine-store/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine-store/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateHandlerInterceptor"
+ },
+ "name": "io.seata.saga.engine.pcext.interceptors.InSagaBranchHandlerInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/saga/seata-saga-engine/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine/reflect-config.json b/saga/seata-saga-engine/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine/reflect-config.json
new file mode 100644
index 00000000000..c0e1bb0ad5c
--- /dev/null
+++ b/saga/seata-saga-engine/src/main/resources/META-INF/native-image/io.seata/seata-saga-engine/reflect-config.json
@@ -0,0 +1,50 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateHandlerInterceptor"
+ },
+ "name": "io.seata.saga.engine.pcext.interceptors.ServiceTaskHandlerInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateHandlerInterceptor"
+ },
+ "name": "io.seata.saga.engine.pcext.interceptors.ScriptTaskHandlerInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateHandlerInterceptor"
+ },
+ "name": "io.seata.saga.engine.pcext.interceptors.LoopTaskHandlerInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateRouterInterceptor"
+ },
+ "name": "io.seata.saga.engine.pcext.interceptors.EndStateRouterInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/saga/seata-saga-rm/src/main/resources/META-INF/native-image/io.seata/seata-saga-rm/reflect-config.json b/saga/seata-saga-rm/src/main/resources/META-INF/native-image/io.seata/seata-saga-rm/reflect-config.json
new file mode 100644
index 00000000000..3fa805310e7
--- /dev/null
+++ b/saga/seata-saga-rm/src/main/resources/META-INF/native-image/io.seata/seata-saga-rm/reflect-config.json
@@ -0,0 +1,26 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.model.ResourceManager"
+ },
+ "name": "io.seata.saga.rm.SagaResourceManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.AbstractRMHandler"
+ },
+ "name": "io.seata.saga.rm.RMHandlerSaga",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/saga/seata-saga-rm/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager b/saga/seata-saga-rm/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
index 69bc38af6f9..4ec5cba1d35 100644
--- a/saga/seata-saga-rm/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
+++ b/saga/seata-saga-rm/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
@@ -1 +1 @@
-io.seata.saga.rm.SagaResourceManager
+io.seata.saga.rm.SagaResourceManager
\ No newline at end of file
diff --git a/saga/seata-saga-statelang/src/main/resources/META-INF/native-image/io.seata/seata-saga-statelang/reflect-config.json b/saga/seata-saga-statelang/src/main/resources/META-INF/native-image/io.seata/seata-saga-statelang/reflect-config.json
new file mode 100644
index 00000000000..006a4cb149b
--- /dev/null
+++ b/saga/seata-saga-statelang/src/main/resources/META-INF/native-image/io.seata/seata-saga-statelang/reflect-config.json
@@ -0,0 +1,26 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.statelang.parser.JsonParser"
+ },
+ "name": "io.seata.saga.statelang.parser.impl.FastjsonParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.statelang.parser.JsonParser"
+ },
+ "name": "io.seata.saga.statelang.parser.impl.JacksonJsonParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/native-image/io.seata/seata-jackson-parser-oracle/reflect-config.json b/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/native-image/io.seata/seata-jackson-parser-oracle/reflect-config.json
new file mode 100644
index 00000000000..057d1b94032
--- /dev/null
+++ b/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/native-image/io.seata/seata-jackson-parser-oracle/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.datasource.undo.parser.spi.JacksonSerializer"
+ },
+ "name": "io.seata.plugin.jackson.parser.oracle.OracleTimestampJacksonSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/io/seata/spring/boot/autoconfigure/provider/SpringBootConfigurationProvider.java b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/io/seata/spring/boot/autoconfigure/provider/SpringBootConfigurationProvider.java
index 4268bca0133..957d11dea8d 100644
--- a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/io/seata/spring/boot/autoconfigure/provider/SpringBootConfigurationProvider.java
+++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/io/seata/spring/boot/autoconfigure/provider/SpringBootConfigurationProvider.java
@@ -16,12 +16,13 @@
package io.seata.spring.boot.autoconfigure.provider;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
-import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.common.holder.ObjectHolder;
@@ -32,8 +33,6 @@
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.cglib.proxy.Enhancer;
-import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.lang.Nullable;
@@ -60,8 +59,8 @@ public class SpringBootConfigurationProvider implements ExtConfigurationProvider
@Override
public Configuration provide(Configuration originalConfiguration) {
- return (Configuration)Enhancer.create(originalConfiguration.getClass(),
- (MethodInterceptor)(proxy, method, args, methodProxy) -> {
+ return (Configuration)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Configuration.class}
+ , (proxy, method, args) -> {
if (method.getName().startsWith(INTERCEPT_METHOD_PREFIX) && args.length > 0) {
Object result;
String rawDataId = (String)args[0];
@@ -115,7 +114,7 @@ public Configuration provide(Configuration originalConfiguration) {
});
}
- private Object getDefaultValueFromPropertyObject(String dataId) throws IllegalAccessException {
+ private Object getDefaultValueFromPropertyObject(String dataId) throws IllegalAccessException, InvocationTargetException {
String propertyPrefix = getPropertyPrefix(dataId);
String propertySuffix = getPropertySuffix(dataId);
@@ -149,17 +148,31 @@ private Object getDefaultValueFromPropertyObject(String dataId) throws IllegalAc
* @author xingfudeshi@gmail.com
*/
@Nullable
- private Object getDefaultValueFromPropertyObject(Object propertyObj, String fieldName) throws IllegalAccessException {
- Optional fieldOptional = Stream.of(propertyObj.getClass().getDeclaredFields())
- .filter(f -> f.getName().equalsIgnoreCase(fieldName)).findAny();
+ private Object getDefaultValueFromPropertyObject(Object propertyObj, String fieldName) throws IllegalAccessException, InvocationTargetException {
+ try {
+ Field field = propertyObj.getClass().getDeclaredField(fieldName);
- // Get defaultValue from the field
- if (fieldOptional.isPresent()) {
- Field field = fieldOptional.get();
if (!Map.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
return field.get(propertyObj);
}
+ } catch (NoSuchFieldException e) {
+ Method method = null;
+ try {
+ method = propertyObj.getClass().getMethod("get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
+ } catch (NoSuchMethodException ex) {
+ try {
+ method = propertyObj.getClass().getMethod("is" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
+ } catch (NoSuchMethodException exc) {
+ LOGGER.warn("The get method not found for the field '{}#{}'.", propertyObj.getClass().getSimpleName(), fieldName);
+ }
+ }
+ if (method != null) {
+ if (!Map.class.isAssignableFrom(method.getReturnType())) {
+ method.setAccessible(true);
+ return method.invoke(propertyObj);
+ }
+ }
}
return null;
diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/proxy-config.json b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/proxy-config.json
new file mode 100644
index 00000000000..86bc6c1305f
--- /dev/null
+++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/proxy-config.json
@@ -0,0 +1,10 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.boot.autoconfigure.provider.SpringBootConfigurationProvider"
+ },
+ "interfaces": [
+ "io.seata.config.Configuration"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/reflect-config.json b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/reflect-config.json
new file mode 100644
index 00000000000..abadecf024e
--- /dev/null
+++ b/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/resources/META-INF/native-image/io.seata/seata-spring-autoconfigure-core/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.config.ExtConfigurationProvider"
+ },
+ "name": "io.seata.spring.boot.autoconfigure.provider.SpringBootConfigurationProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/serializer/seata-serializer-fst/src/main/resources/META-INF/native-image/io.seata/seata-serializer-fst/reflect-config.json b/serializer/seata-serializer-fst/src/main/resources/META-INF/native-image/io.seata/seata-serializer-fst/reflect-config.json
new file mode 100644
index 00000000000..de413f4bd77
--- /dev/null
+++ b/serializer/seata-serializer-fst/src/main/resources/META-INF/native-image/io.seata/seata-serializer-fst/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.Serializer"
+ },
+ "name": "io.seata.serializer.fst.FstSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/serializer/seata-serializer-hessian/src/main/resources/META-INF/native-image/io.seata/seata-serializer-hessian/reflect-config.json b/serializer/seata-serializer-hessian/src/main/resources/META-INF/native-image/io.seata/seata-serializer-hessian/reflect-config.json
new file mode 100644
index 00000000000..4d6f3e586e7
--- /dev/null
+++ b/serializer/seata-serializer-hessian/src/main/resources/META-INF/native-image/io.seata/seata-serializer-hessian/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.Serializer"
+ },
+ "name": "io.seata.serializer.hessian.HessianSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/serializer/seata-serializer-kryo/src/main/resources/META-INF/native-image/io.seata/seata-serializer-kryo/reflect-config.json b/serializer/seata-serializer-kryo/src/main/resources/META-INF/native-image/io.seata/seata-serializer-kryo/reflect-config.json
new file mode 100644
index 00000000000..41aadd953bf
--- /dev/null
+++ b/serializer/seata-serializer-kryo/src/main/resources/META-INF/native-image/io.seata/seata-serializer-kryo/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.Serializer"
+ },
+ "name": "io.seata.serializer.kryo.KryoSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/serializer/seata-serializer-protobuf/src/main/resources/META-INF/native-image/io.seata/seata-serializer-protobuf/reflect-config.json b/serializer/seata-serializer-protobuf/src/main/resources/META-INF/native-image/io.seata/seata-serializer-protobuf/reflect-config.json
new file mode 100644
index 00000000000..0e85dad04ba
--- /dev/null
+++ b/serializer/seata-serializer-protobuf/src/main/resources/META-INF/native-image/io.seata/seata-serializer-protobuf/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.Serializer"
+ },
+ "name": "io.seata.serializer.protobuf.ProtobufSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/serializer/seata-serializer-seata/src/main/resources/META-INF/native-image/io.seata/seata-serializer-seata/reflect-config.json b/serializer/seata-serializer-seata/src/main/resources/META-INF/native-image/io.seata/seata-serializer-seata/reflect-config.json
new file mode 100644
index 00000000000..140bfe99f60
--- /dev/null
+++ b/serializer/seata-serializer-seata/src/main/resources/META-INF/native-image/io.seata/seata-serializer-seata/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.serializer.Serializer"
+ },
+ "name": "io.seata.serializer.seata.SeataSerializer",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/server/pom.xml b/server/pom.xml
index b0eac164b3d..1924128aa50 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -31,6 +31,7 @@
${spring-boot.version}
${spring-framework.version}
+ 0.9.20
@@ -160,7 +161,7 @@
com.h2database
h2
-
+
mysql
mysql-connector-java
@@ -371,6 +372,120 @@
+
+ native
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+ repackage
+
+ repackage
+
+
+
+ process-aot
+
+ process-aot
+
+
+
+
+ io.seata.server.ServerApplication
+
+ paketobuildpacks/builder:tiny
+
+ true
+
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ ${native-build-tools-plugin.version}
+
+ ${project.build.outputDirectory}
+
+ true
+
+ 22.3
+
+ -H:+ReportExceptionStackTraces
+ -H:+PrintAnalysisCallTree
+
+ -H:+ExhaustiveHeapScan
+
+
+
+
+ add-reachability-metadata
+
+ add-reachability-metadata
+
+
+
+ build-native
+
+ compile-no-fork
+
+
+
+
+
+
+
+
+ nativeTest
+
+
+ org.junit.platform
+ junit-platform-launcher
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+ process-test-aot
+
+ process-test-aot
+
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ ${native-build-tools-plugin.version}
+
+ ${project.build.outputDirectory}
+
+ true
+
+ 22.3
+
+
+
+ native-test
+
+ test
+
+
+
+
+
+
+
release-seata
diff --git a/server/src/main/java/io/seata/server/ServerApplication.java b/server/src/main/java/io/seata/server/ServerApplication.java
index e168ad65c06..f61ec5f62a1 100644
--- a/server/src/main/java/io/seata/server/ServerApplication.java
+++ b/server/src/main/java/io/seata/server/ServerApplication.java
@@ -15,8 +15,7 @@
*/
package io.seata.server;
-import java.io.IOException;
-
+import io.seata.common.aot.NativeUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -25,8 +24,26 @@
*/
@SpringBootApplication(scanBasePackages = {"io.seata"})
public class ServerApplication {
- public static void main(String[] args) throws IOException {
- // run the spring-boot application
- SpringApplication.run(ServerApplication.class, args);
+
+ public static void main(String[] args) throws Throwable {
+ try {
+ // run the spring-boot application
+ SpringApplication.run(ServerApplication.class, args);
+ } catch (Throwable t) {
+ // This exception is used to end `spring-boot-maven-plugin:process-aot`, so ignore it.
+ if ("org.springframework.boot.SpringApplication$AbandonedRunException".equals(t.getClass().getName())) {
+ throw t;
+ }
+
+ // In the `native-image`, if an exception occurs prematurely during the startup process, the exception log will not be recorded,
+ // so here we sleep for 20 seconds to observe the exception information.
+ if (NativeUtils.inNativeImage()) {
+ t.printStackTrace();
+ Thread.sleep(20000);
+ }
+
+ throw t;
+ }
}
+
}
diff --git a/server/src/main/java/io/seata/server/console/controller/BranchSessionController.java b/server/src/main/java/io/seata/server/console/controller/BranchSessionController.java
index 62ffac67c06..6310688b11d 100644
--- a/server/src/main/java/io/seata/server/console/controller/BranchSessionController.java
+++ b/server/src/main/java/io/seata/server/console/controller/BranchSessionController.java
@@ -16,12 +16,14 @@
package io.seata.server.console.controller;
import javax.annotation.Resource;
+
import io.seata.server.console.service.BranchSessionService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Branch Session Controller
+ *
* @author zhongxiang.wang
*/
@RestController
@@ -31,5 +33,4 @@ public class BranchSessionController {
@Resource(type = BranchSessionService.class)
private BranchSessionService branchSessionService;
-
}
diff --git a/server/src/main/java/io/seata/server/console/controller/GlobalLockController.java b/server/src/main/java/io/seata/server/console/controller/GlobalLockController.java
index ac20ebf14ba..b9478111859 100644
--- a/server/src/main/java/io/seata/server/console/controller/GlobalLockController.java
+++ b/server/src/main/java/io/seata/server/console/controller/GlobalLockController.java
@@ -17,18 +17,18 @@
import javax.annotation.Resource;
-import io.seata.server.console.param.GlobalLockParam;
import io.seata.console.result.PageResult;
-import io.seata.server.console.vo.GlobalLockVO;
+import io.seata.server.console.param.GlobalLockParam;
import io.seata.server.console.service.GlobalLockService;
+import io.seata.server.console.vo.GlobalLockVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-
/**
* Global Lock Controller
+ *
* @author zhongxiang.wang
*/
@RestController
@@ -40,6 +40,7 @@ public class GlobalLockController {
/**
* Query locks by param
+ *
* @param param the param
* @return the list of GlobalLockVO
*/
diff --git a/server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java b/server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java
index 9bd79d95622..6c7ee50ba9f 100644
--- a/server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java
+++ b/server/src/main/java/io/seata/server/console/controller/GlobalSessionController.java
@@ -17,10 +17,10 @@
import javax.annotation.Resource;
-import io.seata.server.console.param.GlobalSessionParam;
import io.seata.console.result.PageResult;
-import io.seata.server.console.vo.GlobalSessionVO;
+import io.seata.server.console.param.GlobalSessionParam;
import io.seata.server.console.service.GlobalSessionService;
+import io.seata.server.console.vo.GlobalSessionVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,6 +28,7 @@
/**
* Global Session Controller
+ *
* @author zhongxiang.wang
*/
@RestController
@@ -39,8 +40,9 @@ public class GlobalSessionController {
/**
* Query all globalSession
+ *
* @param param param for query globalSession
- * @return the list of GlobalSessionVO
+ * @return the list of GlobalSessionVO
*/
@GetMapping("query")
public PageResult query(@ModelAttribute GlobalSessionParam param) {
diff --git a/server/src/main/resources/META-INF/native-image/io.seata/server/reflect-config.json b/server/src/main/resources/META-INF/native-image/io.seata/server/reflect-config.json
new file mode 100644
index 00000000000..9d762dfbaca
--- /dev/null
+++ b/server/src/main/resources/META-INF/native-image/io.seata/server/reflect-config.json
@@ -0,0 +1,362 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.rpc.RegisterCheckAuthHandler"
+ },
+ "name": "io.seata.server.auth.DefaultCheckAuthHandler",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.DataSourceProvider"
+ },
+ "name": "io.seata.server.store.DbcpDataSourceProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.DataSourceProvider"
+ },
+ "name": "io.seata.server.store.DruidDataSourceProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.db.DataSourceProvider"
+ },
+ "name": "io.seata.server.store.HikariDataSourceProvider",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.DistributedLocker"
+ },
+ "name": "io.seata.server.storage.redis.lock.RedisDistributedLocker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.store.DistributedLocker"
+ },
+ "name": "io.seata.server.storage.db.lock.DataBaseDistributedLocker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.coordinator.AbstractCore"
+ },
+ "name": "io.seata.server.transaction.at.ATCore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.core.rpc.RemotingServer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.coordinator.AbstractCore"
+ },
+ "name": "io.seata.server.transaction.tcc.TccCore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.core.rpc.RemotingServer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.coordinator.AbstractCore"
+ },
+ "name": "io.seata.server.transaction.saga.SagaCore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.core.rpc.RemotingServer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.coordinator.AbstractCore"
+ },
+ "name": "io.seata.server.transaction.xa.XACore",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "io.seata.core.rpc.RemotingServer"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.lock.LockManager"
+ },
+ "name": "io.seata.server.storage.db.lock.DataBaseLockManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.lock.LockManager"
+ },
+ "name": "io.seata.server.storage.file.lock.FileLockManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.lock.LockManager"
+ },
+ "name": "io.seata.server.storage.redis.lock.RedisLockManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.session.SessionManager"
+ },
+ "name": "io.seata.server.storage.file.session.FileSessionManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.lang.String",
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.session.SessionManager"
+ },
+ "name": "io.seata.server.storage.db.session.DataBaseSessionManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ },
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.server.session.SessionManager"
+ },
+ "name": "io.seata.server.storage.redis.session.RedisSessionManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ },
+ {
+ "name": "",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Integer",
+ "methods": [
+ {
+ "name": "parseInteger",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Long",
+ "methods": [
+ {
+ "name": "parseLong",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Boolean",
+ "methods": [
+ {
+ "name": "parseBoolean",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Byte",
+ "methods": [
+ {
+ "name": "parseByte",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Short",
+ "methods": [
+ {
+ "name": "parseShort",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Float",
+ "methods": [
+ {
+ "name": "parseFloat",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "com.google.inject.internal.TypeConverterBindingProcessor"
+ },
+ "name": "java.lang.Double",
+ "methods": [
+ {
+ "name": "parseDouble",
+ "parameterTypes": [
+ "java.lang.String"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.channel.socket.nio.SelectorProviderUtil"
+ },
+ "name": "java.nio.channels.spi.SelectorProvider",
+ "methods": [
+ {
+ "name": "openServerSocketChannel",
+ "parameterTypes": [
+ "java.net.ProtocolFamily"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.channel.DefaultChannelConfig"
+ },
+ "name": "io.netty.buffer.ByteBufAllocator"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.channel.DefaultChannelConfig"
+ },
+ "name": "io.netty.buffer.ByteBufUtil"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.util.ResourceLeakDetector"
+ },
+ "name": "io.netty.buffer.AbstractByteBufAllocator",
+ "allDeclaredMethods": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.util.ResourceLeakDetector"
+ },
+ "name": "io.netty.buffer.AdvancedLeakAwareByteBuf",
+ "allDeclaredMethods": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.netty.util.ResourceLeakDetector"
+ },
+ "name": "io.netty.util.ReferenceCountUtil",
+ "allDeclaredMethods": true
+ }
+]
\ No newline at end of file
diff --git a/server/src/main/resources/META-INF/native-image/io.seata/server/resource-config.json b/server/src/main/resources/META-INF/native-image/io.seata/server/resource-config.json
new file mode 100644
index 00000000000..73b72ff3d84
--- /dev/null
+++ b/server/src/main/resources/META-INF/native-image/io.seata/server/resource-config.json
@@ -0,0 +1,21 @@
+{
+ "resources": {
+ "includes": [
+ {
+ "pattern": "\\Qlogback\/\\E.*"
+ },
+ {
+ "pattern": "\\Qlua\/redislocker\/redislock.lua\\E"
+ },
+ {
+ "pattern": "\\Qapplication.yml\\E"
+ },
+ {
+ "pattern": "\\Qbanner.txt\\E"
+ },
+ {
+ "pattern": "\\Qlogback-spring.xml\\E"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/spring-aot/pom.xml b/spring-aot/pom.xml
new file mode 100644
index 00000000000..b0fb14ed7cf
--- /dev/null
+++ b/spring-aot/pom.xml
@@ -0,0 +1,58 @@
+
+
+
+
+ io.seata
+ seata-parent
+ ${revision}
+
+ 4.0.0
+
+ seata-spring-aot
+ pom
+
+ ${project.artifactId} ${project.version}
+ spring-aot top parent for Seata built with Maven
+
+
+ seata-spring-aot-core
+ seata-spring-aot-client
+
+
+
+
+ org.springframework
+ spring-context
+
+
+
+ ${project.groupId}
+ seata-spring-framework-fake-for-java8
+ ${project.version}
+ provided
+
+
+
+
+
diff --git a/spring-aot/seata-spring-aot-client/pom.xml b/spring-aot/seata-spring-aot-client/pom.xml
new file mode 100644
index 00000000000..52de9fd9751
--- /dev/null
+++ b/spring-aot/seata-spring-aot-client/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+
+ io.seata
+ seata-spring-aot
+ ${revision}
+
+ 4.0.0
+
+ seata-spring-aot-client
+
+ ${project.artifactId} ${project.version}
+ spring-aot-client for Seata built with Maven
+
+
+
+ ${project.groupId}
+ seata-spring-aot-core
+ ${project.version}
+
+
+ ${project.groupId}
+ seata-spring
+ ${project.version}
+
+
+
+ com.alibaba
+ druid
+ provided
+ true
+
+
+
diff --git a/spring-aot/seata-spring-aot-client/src/main/java/io/seata/spring/aot/SeataLocalTCCBeanRegistrationAotProcessor.java b/spring-aot/seata-spring-aot-client/src/main/java/io/seata/spring/aot/SeataLocalTCCBeanRegistrationAotProcessor.java
new file mode 100644
index 00000000000..c6e266d2bf2
--- /dev/null
+++ b/spring-aot/seata-spring-aot-client/src/main/java/io/seata/spring/aot/SeataLocalTCCBeanRegistrationAotProcessor.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed 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 io.seata.spring.aot;
+
+import java.util.Set;
+
+import io.seata.common.util.ReflectionUtil;
+import io.seata.rm.tcc.api.LocalTCC;
+import io.seata.spring.annotation.GlobalTransactionScanner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aot.generate.GenerationContext;
+import org.springframework.aot.hint.ReflectionHints;
+import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
+import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
+import org.springframework.beans.factory.aot.BeanRegistrationCode;
+import org.springframework.beans.factory.support.RegisteredBean;
+
+import static io.seata.spring.aot.AotUtils.ALL_MEMBER_CATEGORIES;
+import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_METHODS;
+
+/**
+ * The seata-client bean registration AOT processor
+ *
+ * @author wang.liang
+ */
+class SeataLocalTCCBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SeataLocalTCCBeanRegistrationAotProcessor.class);
+
+ @Override
+ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
+ Class> beanClass = registeredBean.getBeanClass();
+ if (GlobalTransactionScanner.isTccAutoProxy(beanClass)) {
+ return new SeataTccBeanRegistrationAotContribution(beanClass);
+ }
+ return null;
+ }
+
+
+ /**
+ * The seata tcc bean registration AOT contribution
+ */
+ private static class SeataTccBeanRegistrationAotContribution implements BeanRegistrationAotContribution {
+
+ private final Class> beanClass;
+
+
+ public SeataTccBeanRegistrationAotContribution(Class> beanClass) {
+ this.beanClass = beanClass;
+ }
+
+
+ @Override
+ public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
+ ReflectionHints reflectionHints = generationContext.getRuntimeHints().reflection();
+
+ // register the bean class
+ registerClassAndItsInterfacesIfLocalTcc(reflectionHints, beanClass);
+
+ // register the interface classes
+ Set> interfaceClasses = ReflectionUtil.getInterfaces(beanClass);
+ for (Class> interClass : interfaceClasses) {
+ registerClassAndItsInterfacesIfLocalTcc(reflectionHints, interClass);
+ }
+ }
+
+ private void registerClassAndItsInterfacesIfLocalTcc(ReflectionHints reflectionHints, Class> clazz) {
+ if (clazz.isAnnotationPresent(LocalTCC.class)) {
+ reflectionHints.registerType(clazz, INVOKE_PUBLIC_METHODS);
+ LOGGER.info("TCC: Register reflection type '{}' (annotated `@LocalTCC`) with member categories {}", clazz.getName(), INVOKE_PUBLIC_METHODS);
+ AotUtils.registerAllOfClass(false, reflectionHints, clazz, ALL_MEMBER_CATEGORIES);
+ }
+ }
+ }
+}
diff --git a/spring-aot/seata-spring-aot-client/src/main/resources/META-INF/spring/aot.factories b/spring-aot/seata-spring-aot-client/src/main/resources/META-INF/spring/aot.factories
new file mode 100644
index 00000000000..c58d25f79b4
--- /dev/null
+++ b/spring-aot/seata-spring-aot-client/src/main/resources/META-INF/spring/aot.factories
@@ -0,0 +1,2 @@
+org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
+io.seata.spring.aot.SeataLocalTCCBeanRegistrationAotProcessor
\ No newline at end of file
diff --git a/spring-aot/seata-spring-aot-core/pom.xml b/spring-aot/seata-spring-aot-core/pom.xml
new file mode 100644
index 00000000000..ad270c9d829
--- /dev/null
+++ b/spring-aot/seata-spring-aot-core/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ io.seata
+ seata-spring-aot
+ ${revision}
+
+ 4.0.0
+
+ seata-spring-aot-core
+
+ ${project.artifactId} ${project.version}
+ spring-aot-core for Seata built with Maven
+
+
+
+ ${project.groupId}
+ seata-core
+ ${project.version}
+
+
+
diff --git a/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/AotUtils.java b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/AotUtils.java
new file mode 100644
index 00000000000..1d25d7df30c
--- /dev/null
+++ b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/AotUtils.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed 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 io.seata.spring.aot;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import io.seata.common.aot.NativeUtils;
+import io.seata.common.util.ReflectionUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.ReflectionHints;
+import org.springframework.core.SpringProperties;
+import org.springframework.core.io.Resource;
+import org.springframework.lang.NonNull;
+import org.springframework.lang.Nullable;
+
+import static io.seata.common.loader.EnhancedServiceLoader.SERVICES_DIRECTORY;
+import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_CONSTRUCTORS;
+import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_METHODS;
+
+/**
+ * The AOT utils
+ *
+ * @author wang.liang
+ */
+public class AotUtils extends NativeUtils {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AotUtils.class);
+
+ public static final String SPRING_AOT_ENABLED = "spring.aot.enabled";
+
+
+ /**
+ * Usually used for serialization
+ */
+ public static final MemberCategory[] ALL_MEMBER_CATEGORIES = MemberCategory.values();
+
+ /**
+ * Only used for load class
+ */
+ public static final MemberCategory[] EMPTY_MEMBER_CATEGORIES = new MemberCategory[0];
+
+ public static final MemberCategory[] MEMBER_CATEGORIES_FOR_INSTANTIATE = new MemberCategory[]{INVOKE_DECLARED_CONSTRUCTORS};
+
+ public static final MemberCategory[] MEMBER_CATEGORIES_FOR_INSTANTIATE_AND_INVOKE = new MemberCategory[]{INVOKE_DECLARED_CONSTRUCTORS, INVOKE_DECLARED_METHODS};
+
+
+ /**
+ * Whether AOT enabled
+ *
+ * @return the boolean
+ */
+ public static boolean isSpringAotEnabled() {
+ return SpringProperties.getFlag(SPRING_AOT_ENABLED);
+ }
+
+
+ //region # Register type to ReflectionHints
+
+ public static void registerType(ReflectionHints reflectionHints, Class> clazz, MemberCategory... memberCategories) {
+ reflectionHints.registerType(clazz, memberCategories);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.info("Register reflection type '{}' with member categories {}", clazz.getName(), memberCategories);
+ }
+ }
+
+ public static void registerType(ReflectionHints reflectionHints, String className, MemberCategory... memberCategories) {
+ try {
+ Class> clazz = ReflectionUtil.getClassByName(className);
+ registerType(reflectionHints, clazz, memberCategories);
+ } catch (ClassNotFoundException e) {
+ LOGGER.warn("Register reflection type failed: class not found '{}'.", className);
+ } catch (NoClassDefFoundError e) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.warn("Register reflection type '{}' error:", className, e);
+ } else {
+ LOGGER.warn("Register reflection type '{}' error: {}: {}", className, e.getClass().getName(), e.getMessage());
+ }
+ }
+ }
+
+ public static void registerTypes(ReflectionHints reflectionHints, MemberCategory[] memberCategories, String... classNames) {
+ for (String className : classNames) {
+ try {
+ registerType(reflectionHints, ReflectionUtil.getClassByName(className), memberCategories);
+ } catch (ClassNotFoundException e) {
+ LOGGER.warn("Register reflection type failed: class not found '{}'.", className);
+ } catch (NoClassDefFoundError e) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.warn("Register reflection type '{}' error:", className, e);
+ } else {
+ LOGGER.warn("Register reflection type '{}' error: {}: {}", className, e.getClass().getName(), e.getMessage());
+ }
+ }
+ }
+ }
+
+ public static void registerTypes(ReflectionHints reflectionHints, MemberCategory[] memberCategories, Class>... classes) {
+ for (Class> clazz : classes) {
+ registerType(reflectionHints, clazz, memberCategories);
+ }
+ }
+
+ /**
+ * Register the types for serialize, without knowing the type of the serializer
+ *
+ * @param reflectionHints the reflection hints
+ * @param classes the classes
+ */
+ public static void registerTypesForSerialize(ReflectionHints reflectionHints, Class>... classes) {
+ registerTypes(reflectionHints, ALL_MEMBER_CATEGORIES, classes);
+ }
+
+ public static void registerTypesForSerialize(ReflectionHints reflectionHints, String... classNames) {
+ registerTypes(reflectionHints, ALL_MEMBER_CATEGORIES, classNames);
+ }
+
+
+ //region ## Register 'classpath*:META-INF/services/*' to ReflectionHints
+
+ public static void registerServices(ReflectionHints reflectionHints, String location, @Nullable Predicate predicate, MemberCategory... memberCategories) {
+ Resource[] resources = ResourceUtil.getResources(location);
+ for (Resource resource : resources) {
+ if (predicate != null && !predicate.test(resource)) {
+ continue;
+ }
+
+ try (InputStreamReader isr = new InputStreamReader(resource.getInputStream()); BufferedReader br = new BufferedReader(isr)) {
+ br.lines().forEach(className -> {
+ AotUtils.registerTypes(reflectionHints, memberCategories, className);
+ });
+ } catch (IOException e) {
+ LOGGER.error("Register services '{}' fail:", resource.getFilename(), e);
+ }
+ }
+ }
+
+ public static void registerServices(ReflectionHints reflectionHints, String location, MemberCategory... memberCategories) {
+ registerServices(reflectionHints, location, null, memberCategories);
+ }
+
+ public static void registerServices(ReflectionHints reflectionHints, @Nullable Predicate predicate, MemberCategory... memberCategories) {
+ registerServices(reflectionHints, "classpath*:" + SERVICES_DIRECTORY + "*", predicate, memberCategories);
+ }
+
+ public static void registerServices(ReflectionHints reflectionHints, MemberCategory... memberCategories) {
+ registerServices(reflectionHints, "classpath*:" + SERVICES_DIRECTORY + "*", null, memberCategories);
+ }
+
+ //endregion ##
+
+
+ //region ## Register all of class to ReflectionHints
+
+ /**
+ * Recursively register the class and its supper classes, interfaces, fields, and the parameters of methods to the reflection hints.
+ *
+ * @param clazz the class
+ * @param registerSelf whether register self
+ * @param reflectionHints the reflection hints
+ * @param memberCategories the member categories
+ */
+ public static void registerAllOfClass(boolean registerSelf, ReflectionHints reflectionHints, Class> clazz, MemberCategory... memberCategories) {
+ registerAllOfClassInternal(new HashSet<>(), registerSelf, reflectionHints, clazz, memberCategories);
+ }
+
+ private static void registerAllOfClassInternal(@NonNull Set> cache, boolean registerSelf, ReflectionHints reflectionHints, Class> clazz, MemberCategory... memberCategories) {
+ if (clazz == null) {
+ return;
+ }
+
+ if (clazz.isPrimitive() || clazz.isEnum() || clazz.isAnnotation()) {
+ return;
+ }
+
+ if (clazz.isArray()) {
+ registerAllOfClassInternal(cache, true, reflectionHints, clazz.getComponentType(), memberCategories);
+ return;
+ }
+
+ if (ReflectionUtil.isJavaClass(clazz)) {
+ return;
+ }
+
+ // Cached to prevent endless loops
+ if (cache.contains(clazz)) {
+ return;
+ }
+ cache.add(clazz);
+
+ // register self
+ if (registerSelf) {
+ registerType(reflectionHints, clazz, memberCategories);
+ }
+
+ // register the interfaces
+ Set> interfaceClasses = ReflectionUtil.getInterfaces(clazz);
+ for (Class> interfaceClass : interfaceClasses) {
+ if (!interfaceClass.equals(clazz)) {
+ registerAllOfClassInternal(cache, true, reflectionHints, interfaceClass, memberCategories);
+ }
+ }
+
+ // register the supper class
+ registerAllOfClassInternal(cache, true, reflectionHints, clazz.getSuperclass(), memberCategories);
+
+ // register the fields
+ Field[] fields = ReflectionUtil.getAllFields(clazz);
+ for (Field field : fields) {
+ registerAllOfClassInternal(cache, true, reflectionHints, field.getType(), memberCategories);
+ }
+
+ // register the parameters of methods
+ Method[] methods = clazz.getMethods();
+ for (Method method : methods) {
+ Class>[] parameterTypes = method.getParameterTypes();
+ for (Class> parameterType : parameterTypes) {
+ registerAllOfClassInternal(cache, true, reflectionHints, parameterType, memberCategories);
+ }
+ }
+ }
+
+ //endregion ##
+
+ //endregion #
+}
diff --git a/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/ResourceUtil.java b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/ResourceUtil.java
new file mode 100644
index 00000000000..6d21deb3c7f
--- /dev/null
+++ b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/ResourceUtil.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed 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 io.seata.spring.aot;
+
+import java.io.IOException;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+/**
+ * Resource util.
+ *
+ * @author wang.liang
+ */
+class ResourceUtil {
+
+ private static final ResourcePatternResolver RESOURCE_RESOLVER = new PathMatchingResourcePatternResolver();
+
+ public static Resource[] getResources(String location) {
+ try {
+ return RESOURCE_RESOLVER.getResources(location);
+ } catch (IOException e) {
+ return new Resource[0];
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/SeataServicesRuntimeHints.java b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/SeataServicesRuntimeHints.java
new file mode 100644
index 00000000000..1d4412790db
--- /dev/null
+++ b/spring-aot/seata-spring-aot-core/src/main/java/io/seata/spring/aot/SeataServicesRuntimeHints.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * Licensed 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 io.seata.spring.aot;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.RuntimeHintsRegistrar;
+import org.springframework.core.io.Resource;
+import org.springframework.lang.Nullable;
+
+import static io.seata.common.loader.EnhancedServiceLoader.SEATA_DIRECTORY;
+import static io.seata.common.loader.EnhancedServiceLoader.SERVICES_DIRECTORY;
+
+/**
+ * The seata /META-INF/services runtime hints registrar
+ *
+ * @author wang.liang
+ */
+class SeataServicesRuntimeHints implements RuntimeHintsRegistrar {
+
+ private static final Set OTHER_SERVICES = new HashSet<>();
+
+ static {
+ OTHER_SERVICES.add("com.alibaba.dubbo.rpc.Filter");
+ OTHER_SERVICES.add("com.alipay.sofa.rpc.filter.Filter");
+ OTHER_SERVICES.add("com.taobao.hsf.invocation.filter.RPCFilter");
+ OTHER_SERVICES.add("com.weibo.api.motan.filter.Filter");
+ }
+
+
+ @Override
+ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
+ // Register the services to reflection hints in 'META-INF/services', only the services required by seata.
+ Predicate predicate = this::isSeataServicesResource;
+ AotUtils.registerServices(hints.reflection(), "classpath*:" + SERVICES_DIRECTORY + "*", predicate, AotUtils.MEMBER_CATEGORIES_FOR_INSTANTIATE);
+ AotUtils.registerServices(hints.reflection(), "classpath*:" + SEATA_DIRECTORY + "*", predicate, AotUtils.MEMBER_CATEGORIES_FOR_INSTANTIATE);
+ }
+
+
+ private boolean isSeataServicesResource(Resource resource) {
+ if (resource.getFilename() == null) {
+ return false;
+ }
+
+ if (resource.getFilename().startsWith("io.seata.")) {
+ return true;
+ }
+
+ return OTHER_SERVICES.contains(resource.getFilename());
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/pom.xml b/spring-framework-fake-for-java8/pom.xml
new file mode 100644
index 00000000000..993c0fd2b25
--- /dev/null
+++ b/spring-framework-fake-for-java8/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+
+ io.seata
+ seata-parent
+ ${revision}
+
+ 4.0.0
+
+ seata-spring-framework-fake-for-java8
+
+ ${project.artifactId} ${project.version}
+ spring-framework-fake-for-java8 for Seata built with Maven
+
+
+
+ org.springframework
+ spring-beans
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+
+ true
+
+
+
+
+
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/generate/GenerationContext.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/generate/GenerationContext.java
new file mode 100644
index 00000000000..e226ca4b6b9
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/generate/GenerationContext.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.generate;
+
+import org.springframework.aot.hint.RuntimeHints;
+
+/**
+ * GenerationContext's fake
+ *
+ * @author Phillip Webb
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+public interface GenerationContext {
+
+// GeneratedClasses getGeneratedClasses();
+//
+// GeneratedFiles getGeneratedFiles();
+
+ RuntimeHints getRuntimeHints();
+
+ GenerationContext withName(String name);
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ExecutableMode.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ExecutableMode.java
new file mode 100644
index 00000000000..6ee04575cf2
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ExecutableMode.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import org.springframework.lang.Nullable;
+
+/**
+ * ExecutableMode's fake
+ *
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+public enum ExecutableMode {
+
+ INTROSPECT,
+
+ INVOKE;
+
+ boolean includes(@Nullable ExecutableMode other) {
+ return true;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/MemberCategory.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/MemberCategory.java
new file mode 100644
index 00000000000..d1c47657421
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/MemberCategory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+/**
+ * MemberCategory's fake
+ *
+ * @author Andy Clement
+ * @author Sebastien Deleuze
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+public enum MemberCategory {
+
+ PUBLIC_FIELDS,
+
+ DECLARED_FIELDS,
+
+ INTROSPECT_PUBLIC_CONSTRUCTORS,
+
+ INTROSPECT_DECLARED_CONSTRUCTORS,
+
+ INVOKE_PUBLIC_CONSTRUCTORS,
+
+ INVOKE_DECLARED_CONSTRUCTORS,
+
+ INTROSPECT_PUBLIC_METHODS,
+
+ INTROSPECT_DECLARED_METHODS,
+
+ INVOKE_PUBLIC_METHODS,
+
+ INVOKE_DECLARED_METHODS,
+
+ PUBLIC_CLASSES,
+
+ DECLARED_CLASSES;
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ProxyHints.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ProxyHints.java
new file mode 100644
index 00000000000..509953be3a3
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ProxyHints.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+/**
+ * ProxyHints's fake
+ *
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+public class ProxyHints {
+
+// public Stream jdkProxyHints() {
+// return null;
+// }
+//
+// public ProxyHints registerJdkProxy(Consumer jdkProxyHint) {
+// return this;
+// }
+
+ public ProxyHints registerJdkProxy(TypeReference... proxiedInterfaces) {
+ return this;
+ }
+
+ public ProxyHints registerJdkProxy(Class>... proxiedInterfaces) {
+ return this;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ReflectionHints.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ReflectionHints.java
new file mode 100644
index 00000000000..d84b1b742e9
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ReflectionHints.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import org.springframework.lang.Nullable;
+
+/**
+ * ReflectionHints's fake
+ *
+ * @author Stephane Nicoll
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @since 6.0
+ */
+public class ReflectionHints {
+
+// public Stream typeHints() {
+// return null;
+// }
+//
+// @Nullable
+// public TypeHint getTypeHint(TypeReference type) {
+// return null;
+// }
+//
+// @Nullable
+// public TypeHint getTypeHint(Class> type) {
+// return null;
+// }
+//
+// public ReflectionHints registerType(TypeReference type, Consumer typeHint) {
+// return this;
+// }
+
+ public ReflectionHints registerType(TypeReference type, MemberCategory... memberCategories) {
+ return this;
+ }
+
+// public ReflectionHints registerType(Class> type, Consumer typeHint) {
+// return this;
+// }
+
+ public ReflectionHints registerType(Class> type, MemberCategory... memberCategories) {
+ return this;
+ }
+
+// public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
+// String typeName, Consumer typeHint) {
+// return this;
+// }
+
+ public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
+ String typeName, MemberCategory... memberCategories) {
+ return this;
+ }
+
+// public ReflectionHints registerTypes(Iterable types, Consumer typeHint) {
+// return this;
+// }
+
+ public ReflectionHints registerField(Field field) {
+ return this;
+ }
+
+ public ReflectionHints registerConstructor(Constructor> constructor, ExecutableMode mode) {
+ return this;
+ }
+
+ public ReflectionHints registerMethod(Method method, ExecutableMode mode) {
+ return this;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ResourceHints.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ResourceHints.java
new file mode 100644
index 00000000000..1f679d84dcb
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/ResourceHints.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import org.springframework.core.io.Resource;
+
+/**
+ * ResourceHints's fake
+ *
+ * @author Stephane Nicoll
+ * @author Sam Brannen
+ * @since 6.0
+ */
+public class ResourceHints {
+
+// public Stream resourcePatternHints() {
+// return null;
+// }
+//
+// public Stream resourceBundleHints() {
+// return null;
+// }
+//
+// public ResourceHints registerPatternIfPresent(@Nullable ClassLoader classLoader, String location,
+// Consumer resourceHint) {
+// return this;
+// }
+//
+// public ResourceHints registerPattern(@Nullable Consumer resourceHint) {
+// return this;
+// }
+
+ public ResourceHints registerPattern(String include) {
+ return this;
+ }
+
+ public void registerResource(Resource resource) {
+ }
+
+// public ResourceHints registerType(TypeReference type) {
+// return this;
+// }
+
+ public ResourceHints registerType(Class> type) {
+ return this;
+ }
+
+// public ResourceHints registerResourceBundle(String baseName, @Nullable Consumer resourceHint) {
+// return this;
+// }
+
+ public ResourceHints registerResourceBundle(String baseName) {
+ return this;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHints.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHints.java
new file mode 100644
index 00000000000..4bb99528d1d
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHints.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+/**
+ * RuntimeHints's fake
+ *
+ * @author Stephane Nicoll
+ * @author Janne Valkealahti
+ * @since 6.0
+ */
+public class RuntimeHints {
+
+ public ReflectionHints reflection() {
+ return null;
+ }
+
+ public ResourceHints resources() {
+ return null;
+ }
+
+ public SerializationHints serialization() {
+ return null;
+ }
+
+ public ProxyHints proxies() {
+ return null;
+ }
+
+ public ReflectionHints jni() {
+ return null;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHintsRegistrar.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHintsRegistrar.java
new file mode 100644
index 00000000000..caf9898d155
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/RuntimeHintsRegistrar.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import org.springframework.lang.Nullable;
+
+/**
+ * RuntimeHintsRegistrar's fake
+ *
+ * @author Brian Clozel
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+@FunctionalInterface
+public interface RuntimeHintsRegistrar {
+
+ void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader);
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/SerializationHints.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/SerializationHints.java
new file mode 100644
index 00000000000..9a0a7bf5ce3
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/SerializationHints.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import java.io.Serializable;
+
+/**
+ * SerializationHints's fake
+ *
+ * @author Stephane Nicoll
+ * @since 6.0
+ * @see Serializable
+ */
+public class SerializationHints {
+
+// public Stream javaSerializationHints() {
+// return null;
+// }
+//
+// public SerializationHints registerType(TypeReference type, @Nullable Consumer serializationHint) {
+// return this;
+// }
+
+ public SerializationHints registerType(TypeReference type) {
+ return this;
+ }
+
+// public SerializationHints registerType(Class extends Serializable> type, @Nullable Consumer serializationHint) {
+// return this;
+// }
+
+ public SerializationHints registerType(Class extends Serializable> type) {
+ return this;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/TypeReference.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/TypeReference.java
new file mode 100644
index 00000000000..69463bbba32
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/aot/hint/TypeReference.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.aot.hint;
+
+import java.util.List;
+
+import org.springframework.lang.Nullable;
+
+/**
+ * TypeReference's fake
+ *
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+public interface TypeReference {
+
+ String getName();
+
+ String getCanonicalName();
+
+ String getPackageName();
+
+ String getSimpleName();
+
+ @Nullable
+ TypeReference getEnclosingType();
+
+ static TypeReference of(Class> type) {
+ return null;
+ }
+
+ static TypeReference of(String className) {
+ return null;
+ }
+
+ static List listOf(Class>... types) {
+ return null;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotContribution.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotContribution.java
new file mode 100644
index 00000000000..c1d8ffcc346
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotContribution.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.beans.factory.aot;
+
+import org.springframework.aot.generate.GenerationContext;
+
+/**
+ * BeanRegistrationAotContribution's fake
+ *
+ * @author Phillip Webb
+ * @author Stephane Nicoll
+ * @since 6.0
+ * @see BeanRegistrationAotProcessor
+ */
+@FunctionalInterface
+public interface BeanRegistrationAotContribution {
+
+// default BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(
+// GenerationContext generationContext, BeanRegistrationCodeFragments codeFragments) {
+// return codeFragments;
+// }
+
+ void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode);
+
+// static BeanRegistrationAotContribution withCustomCodeFragments(UnaryOperator defaultCodeFragments) {
+// return null;
+// }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotProcessor.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotProcessor.java
new file mode 100644
index 00000000000..d83519f2cfe
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotProcessor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.beans.factory.aot;
+
+import org.springframework.beans.factory.support.RegisteredBean;
+import org.springframework.lang.Nullable;
+
+/**
+ * BeanRegistrationAotProcessor's fake
+ *
+ * @author Phillip Webb
+ * @author Stephane Nicoll
+ * @since 6.0
+ */
+@FunctionalInterface
+public interface BeanRegistrationAotProcessor {
+
+ @Nullable
+ BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean);
+
+ default boolean isBeanExcludedFromAotProcessing() {
+ return true;
+ }
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCode.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCode.java
new file mode 100644
index 00000000000..4fe0eb4aab1
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCode.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.beans.factory.aot;
+
+/**
+ * BeanRegistrationCode's fake
+ *
+ * @author Phillip Webb
+ * @since 6.0
+ */
+public interface BeanRegistrationCode {
+
+// ClassName getClassName();
+//
+// GeneratedMethods getMethods();
+//
+// void addInstancePostProcessor(MethodReference methodReference);
+
+}
diff --git a/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/support/RegisteredBean.java b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/support/RegisteredBean.java
new file mode 100644
index 00000000000..e698f6554e9
--- /dev/null
+++ b/spring-framework-fake-for-java8/src/main/java/org/springframework/beans/factory/support/RegisteredBean.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2002-2022 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.beans.factory.support;
+
+import java.lang.reflect.Executable;
+import java.util.function.Supplier;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.core.ResolvableType;
+import org.springframework.lang.Nullable;
+
+/**
+ * RegisteredBean's fake
+ *
+ * @author Phillip Webb
+ * @since 6.0
+ */
+public final class RegisteredBean {
+
+ private RegisteredBean(ConfigurableListableBeanFactory beanFactory, Supplier beanName,
+ boolean generatedBeanName, Supplier mergedBeanDefinition,
+ @Nullable RegisteredBean parent) {
+ }
+
+
+ public static RegisteredBean of(ConfigurableListableBeanFactory beanFactory, String beanName) {
+ return null;
+ }
+
+ public static RegisteredBean ofInnerBean(RegisteredBean parent, BeanDefinitionHolder innerBean) {
+ return null;
+ }
+
+ public static RegisteredBean ofInnerBean(RegisteredBean parent, BeanDefinition innerBeanDefinition) {
+ return null;
+ }
+
+ public static RegisteredBean ofInnerBean(RegisteredBean parent,
+ @Nullable String innerBeanName, BeanDefinition innerBeanDefinition) {
+ return null;
+ }
+
+
+ public String getBeanName() {
+ return null;
+ }
+
+ public boolean isGeneratedBeanName() {
+ return true;
+ }
+
+ public ConfigurableListableBeanFactory getBeanFactory() {
+ return null;
+ }
+
+ public Class> getBeanClass() {
+ return null;
+ }
+
+ public ResolvableType getBeanType() {
+ return null;
+ }
+
+ public RootBeanDefinition getMergedBeanDefinition() {
+ return null;
+ }
+
+ public boolean isInnerBean() {
+ return true;
+ }
+
+ @Nullable
+ public RegisteredBean getParent() {
+ return null;
+ }
+
+ public Executable resolveConstructorOrFactoryMethod() {
+ return null;
+ }
+
+}
diff --git a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
index ef455ea6e54..435b660b267 100644
--- a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
+++ b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
@@ -25,7 +25,9 @@
import javax.annotation.Nullable;
+import io.seata.common.aot.NativeUtils;
import io.seata.common.util.CollectionUtils;
+import io.seata.common.util.ReflectionUtil;
import io.seata.common.util.StringUtils;
import io.seata.config.ConfigurationCache;
import io.seata.config.ConfigurationChangeEvent;
@@ -36,6 +38,7 @@
import io.seata.core.rpc.netty.RmNettyRemotingClient;
import io.seata.core.rpc.netty.TmNettyRemotingClient;
import io.seata.rm.RMClient;
+import io.seata.rm.tcc.api.LocalTCC;
import io.seata.spring.annotation.scannercheckers.PackageScannerChecker;
import io.seata.spring.tcc.TccActionInterceptor;
import io.seata.spring.util.OrderUtil;
@@ -492,9 +495,31 @@ private MethodDesc makeMethodDesc(GlobalTransactional anno, Method method) {
return new MethodDesc(anno, method);
}
+ public static boolean isTccAutoProxy(Class> beanClass) {
+ Set> interfaceClasses = ReflectionUtil.getInterfaces(beanClass);
+ for (Class> interClass : interfaceClasses) {
+ if (interClass.isAnnotationPresent(LocalTCC.class)) {
+ return true;
+ }
+ }
+ return beanClass.isAnnotationPresent(LocalTCC.class);
+ }
+
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource customTargetSource)
throws BeansException {
+ if (NativeUtils.isSpringAotProcessing()) {
+ if (isTccAutoProxy(beanClass)) {
+ LOGGER.info("Proxy TCC service: {}", beanName);
+ return new Object[]{new TccActionInterceptor()};
+ } else if (existsAnnotation(beanClass)) {
+ LOGGER.info("Proxy TM bean: {}", beanName);
+ return new Object[]{new GlobalTransactionalInterceptor(failureHandlerHook)};
+ } else {
+ return DO_NOT_PROXY;
+ }
+ }
+
return new Object[]{interceptor};
}
diff --git a/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyCreator.java b/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyCreator.java
index b5fdb69d4d3..39b4fbe163a 100644
--- a/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyCreator.java
+++ b/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyCreator.java
@@ -15,11 +15,12 @@
*/
package io.seata.spring.annotation.datasource;
-import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import javax.sql.DataSource;
+import io.seata.common.aot.NativeUtils;
import io.seata.core.model.BranchType;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.SeataDataSourceProxy;
@@ -59,6 +60,15 @@ private Object[] buildAdvisors(String dataSourceProxyMode) {
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class> beanClass, String beanName, TargetSource customTargetSource) {
+ if (NativeUtils.isSpringAotProcessing()) {
+ if (!DataSource.class.isAssignableFrom(beanClass)) {
+ return DO_NOT_PROXY;
+ }
+
+ if (this.shouldSkip(beanClass, beanName)) {
+ return DO_NOT_PROXY;
+ }
+ }
return advisors;
}
diff --git a/spring/src/main/resources/META-INF/native-image/io.seata/seata-spring/reflect-config.json b/spring/src/main/resources/META-INF/native-image/io.seata/seata-spring/reflect-config.json
new file mode 100644
index 00000000000..9557379d24d
--- /dev/null
+++ b/spring/src/main/resources/META-INF/native-image/io.seata/seata-spring/reflect-config.json
@@ -0,0 +1,57 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.annotation.datasource.SeataAutoDataSourceProxyAdvice"
+ },
+ "name": "javax.sql.DataSource",
+ "allDeclaredMethods": true
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.tcc.TccAnnotationProcessor"
+ },
+ "name": "org.apache.dubbo.config.annotation.Reference"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.tcc.TccAnnotationProcessor"
+ },
+ "name": "com.alipay.sofa.runtime.api.annotation.SofaReference"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.annotation.ScannerChecker"
+ },
+ "name": "io.seata.spring.annotation.scannercheckers.PackageScannerChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.annotation.ScannerChecker"
+ },
+ "name": "io.seata.spring.annotation.scannercheckers.ConfigBeansScannerChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.spring.annotation.ScannerChecker"
+ },
+ "name": "io.seata.spring.annotation.scannercheckers.ScopeBeansScannerChecker",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-antlr/reflect-config.json b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-antlr/reflect-config.json
new file mode 100644
index 00000000000..dac2a097694
--- /dev/null
+++ b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-antlr/reflect-config.json
@@ -0,0 +1,38 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.antlr.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.antlr.mysql.MySQLOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.SQLRecognizerFactory"
+ },
+ "name": "io.seata.sqlparser.antlr.AntlrDelegatingSQLRecognizerFactory",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.antlr.AntlrDelegatingSQLRecognizerFactory"
+ },
+ "name": "io.seata.sqlparser.antlr.mysql.AntlrMySQLRecognizerFactory",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
index f8b91af9ded..492fd8b21f5 100644
--- a/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
+++ b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
@@ -1 +1 @@
-io.seata.sqlparser.antlr.AntlrDelegatingSQLRecognizerFactory
+io.seata.sqlparser.antlr.AntlrDelegatingSQLRecognizerFactory
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.antlr.SQLOperateRecognizerHolder b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.antlr.SQLOperateRecognizerHolder
index 177e9a18ffa..f3fa7ac6320 100644
--- a/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.antlr.SQLOperateRecognizerHolder
+++ b/sqlparser/seata-sqlparser-antlr/src/main/resources/META-INF/services/io.seata.sqlparser.antlr.SQLOperateRecognizerHolder
@@ -1 +1 @@
-io.seata.sqlparser.antlr.mysql.MySQLOperateRecognizerHolder
+io.seata.sqlparser.antlr.mysql.MySQLOperateRecognizerHolder
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/reflect-config.json b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/reflect-config.json
new file mode 100644
index 00000000000..a174a6e7942
--- /dev/null
+++ b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/reflect-config.json
@@ -0,0 +1,86 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.DruidDelegatingDbTypeParser"
+ },
+ "name": "io.seata.sqlparser.druid.DruidDbTypeParserImpl",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory"
+ },
+ "name": "io.seata.sqlparser.druid.DruidSQLRecognizerFactoryImpl",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.mysql.MySQLOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.oracle.OracleOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.SQLOperateRecognizerHolder"
+ },
+ "name": "io.seata.sqlparser.druid.postgresql.PostgresqlOperateRecognizerHolder",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.SQLRecognizerFactory"
+ },
+ "name": "io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.util.DbTypeParser"
+ },
+ "name": "io.seata.sqlparser.druid.DruidDelegatingDbTypeParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/resource-config.json b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/resource-config.json
new file mode 100644
index 00000000000..2b4710d907e
--- /dev/null
+++ b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/native-image/io.seata/seata-sqlparser-druid/resource-config.json
@@ -0,0 +1,12 @@
+{
+ "resources": {
+ "includes": [
+ {
+ "condition": {
+ "typeReachable": "io.seata.sqlparser.druid.DefaultDruidLoader"
+ },
+ "pattern": "\\Qlib\/sqlparser\/druid.jar\\E"
+ }
+ ]
+ }
+}
diff --git a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
index aeb0a351b7f..e360e22891c 100644
--- a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
+++ b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.SQLRecognizerFactory
@@ -1 +1 @@
-io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory
+io.seata.sqlparser.druid.DruidDelegatingSQLRecognizerFactory
\ No newline at end of file
diff --git a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
index a7a3494b374..a1eca58fd2a 100644
--- a/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
+++ b/sqlparser/seata-sqlparser-druid/src/main/resources/META-INF/services/io.seata.sqlparser.util.DbTypeParser
@@ -1 +1 @@
-io.seata.sqlparser.druid.DruidDelegatingDbTypeParser
+io.seata.sqlparser.druid.DruidDelegatingDbTypeParser
\ No newline at end of file
diff --git a/style/seata_suppressions.xml b/style/seata_suppressions.xml
index eb7923380da..a933135d00b 100644
--- a/style/seata_suppressions.xml
+++ b/style/seata_suppressions.xml
@@ -31,4 +31,6 @@
files="[\\/]antlr[\\/]mysql[\\/]antlr[\\/]"/>
+
\ No newline at end of file
diff --git a/tcc/src/main/resources/META-INF/native-image/io.seata/seata-tcc/reflect-config.json b/tcc/src/main/resources/META-INF/native-image/io.seata/seata-tcc/reflect-config.json
new file mode 100644
index 00000000000..8b2f82a9ebd
--- /dev/null
+++ b/tcc/src/main/resources/META-INF/native-image/io.seata/seata-tcc/reflect-config.json
@@ -0,0 +1,98 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.parser.HSFRemotingParser"
+ },
+ "name": "com.taobao.hsf.app.api.util.HSFApiConsumerBean"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.parser.HSFRemotingParser"
+ },
+ "name": "com.taobao.hsf.app.api.util.HSFApiProviderBean"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.parser.HSFRemotingParser"
+ },
+ "name": "com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.parser.HSFRemotingParser"
+ },
+ "name": "com.taobao.hsf.app.spring.util.HSFSpringProviderBean"
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.model.ResourceManager"
+ },
+ "name": "io.seata.rm.tcc.TCCResourceManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.AbstractRMHandler"
+ },
+ "name": "io.seata.rm.tcc.RMHandlerTCC",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.RemotingParser"
+ },
+ "name": "io.seata.rm.tcc.remoting.parser.DubboRemotingParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.RemotingParser"
+ },
+ "name": "io.seata.rm.tcc.remoting.parser.LocalTCCRemotingParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.RemotingParser"
+ },
+ "name": "io.seata.rm.tcc.remoting.parser.SofaRpcRemotingParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.rm.tcc.remoting.RemotingParser"
+ },
+ "name": "io.seata.rm.tcc.remoting.parser.HSFRemotingParser",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/tcc/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager b/tcc/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
index b572908a4c9..c1b29118bb3 100644
--- a/tcc/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
+++ b/tcc/src/main/resources/META-INF/services/io.seata.core.model.ResourceManager
@@ -1 +1 @@
-io.seata.rm.tcc.TCCResourceManager
+io.seata.rm.tcc.TCCResourceManager
\ No newline at end of file
diff --git a/test/src/test/resources/META-INF/native-image/io.seata/seata-test/reflect-config.json b/test/src/test/resources/META-INF/native-image/io.seata/seata-test/reflect-config.json
new file mode 100644
index 00000000000..769abd68314
--- /dev/null
+++ b/test/src/test/resources/META-INF/native-image/io.seata/seata-test/reflect-config.json
@@ -0,0 +1,50 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.LoaderTestSPI"
+ },
+ "name": "io.seata.common.loader.LoaderTestImpl1",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.common.loader.LoaderTestSPI"
+ },
+ "name": "io.seata.common.loader.LoaderTestImpl2",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateHandlerInterceptor"
+ },
+ "name": "io.seata.saga.engine.mock.MockStateHandlerInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReachable": "io.seata.saga.engine.pcext.StateRouterInterceptor"
+ },
+ "name": "io.seata.saga.engine.mock.MockStateRouterInterceptor",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/tm/src/main/resources/META-INF/native-image/io.seata/seata-tm/reflect-config.json b/tm/src/main/resources/META-INF/native-image/io.seata/seata-tm/reflect-config.json
new file mode 100644
index 00000000000..b108a5bb2e3
--- /dev/null
+++ b/tm/src/main/resources/META-INF/native-image/io.seata/seata-tm/reflect-config.json
@@ -0,0 +1,14 @@
+[
+ {
+ "condition": {
+ "typeReachable": "io.seata.core.model.TransactionManager"
+ },
+ "name": "io.seata.tm.DefaultTransactionManager",
+ "methods": [
+ {
+ "name": "",
+ "parameterTypes": []
+ }
+ ]
+ }
+]
\ No newline at end of file