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 type, @Nullable Consumer serializationHint) { +// return this; +// } + + public SerializationHints registerType(Class 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