diff --git a/.github/workflows/graalvm.yml b/.github/workflows/graalvm.yml
new file mode 100644
index 0000000000..fcff1f14e3
--- /dev/null
+++ b/.github/workflows/graalvm.yml
@@ -0,0 +1,47 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: NativeTest CI - GraalVM Native Image
+
+on:
+ pull_request:
+ branches: [ master ]
+ paths:
+ - '.github/workflows/graalvm.yml'
+ - 'reachability-metadata/src/**'
+ - 'test/native/native-image-filter/**'
+ - 'test/native/src/**'
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ java: [ '22.0.2' ]
+ os: [ 'ubuntu-latest' ]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up GraalVM CE ${{ matrix.java }}
+ uses: graalvm/setup-graalvm@v1
+ with:
+ java-version: ${{ matrix.java }}
+ distribution: 'graalvm-community'
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ cache: 'maven'
+ - name: Run nativeTest with GraalVM CE for ${{ matrix.java-version }}
+ continue-on-error: true
+ run: ./mvnw -PnativeTestInElasticJob -T1C -B -e clean test
diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml
index 75ae790343..4606a518dd 100644
--- a/bootstrap/pom.xml
+++ b/bootstrap/pom.xml
@@ -62,6 +62,11 @@
elasticjob-tracing-rdb
${project.parent.version}
+
+ org.apache.shardingsphere.elasticjob
+ elasticjob-reachability-metadata
+ ${project.version}
+
org.apache.shardingsphere.elasticjob
diff --git a/docs/content/user-manual/configuration/graalvm-native-image.cn.md b/docs/content/user-manual/configuration/graalvm-native-image.cn.md
new file mode 100644
index 0000000000..09f85ca46c
--- /dev/null
+++ b/docs/content/user-manual/configuration/graalvm-native-image.cn.md
@@ -0,0 +1,166 @@
++++
+title = "GraalVM Native Image 支持"
+weight = 6
+chapter = true
++++
+
+## 背景信息
+
+ElasticJob 已在 GraalVM Native Image 下完成可用性验证。
+
+构建包含 `org.apache.shardingsphere.elasticjob:elasticjob-bootstrap:${elasticjob.version}` 的 Maven 依赖的 GraalVM Native Image,
+你需要借助于 GraalVM Native Build Tools。
+GraalVM Native Build Tools 提供了 Maven Plugin 和 Gradle Plugin 来简化 GraalVM CE 的 `native-image` 命令行工具的长篇大论的 shell 命令。
+
+ElasticJob 要求在如下或更高版本的 `GraalVM CE` 完成构建 GraalVM Native Image。使用者可通过 SDKMAN! 快速切换 JDK。这同理
+适用于 https://sdkman.io/jdks#graal , https://sdkman.io/jdks#nik 和 https://sdkman.io/jdks#mandrel 等 `GraalVM CE` 的下游发行版。
+
+- GraalVM CE For JDK 22.0.2,对应于 SDKMAN! 的 `22.0.2-graalce`
+
+用户依然可以使用 SDKMAN! 上的 `21.0.2-graalce` 等旧版本的 GraalVM CE 来构建 ShardingSphere 的 GraalVM Native Image 产物。
+ElasticJob 不为已停止维护的 GraalVM CE 版本设置 CI。
+
+## 使用 ElasticJob 的 Java API
+
+### Maven 生态
+
+使用者需要主动使用 GraalVM Reachability Metadata 中央仓库。
+如下配置可供参考,以配置项目额外的 Maven Profiles,以 GraalVM Native Build Tools 的文档为准。
+
+```xml
+
+
+
+ org.apache.shardingsphere.elasticjob
+ elasticjob-bootstrap
+ ${elasticjob.version}
+ test
+
+
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ 0.10.2
+ true
+
+
+ build-native
+
+ compile-no-fork
+
+ package
+
+
+ test-native
+
+ test
+
+ test
+
+
+
+
+
+
+```
+
+### Gradle 生态
+
+使用者需要主动使用 GraalVM Reachability Metadata 中央仓库。
+如下配置可供参考,以配置项目额外的 Gradle Tasks,以 GraalVM Native Build Tools 的文档为准。
+由于 https://github.com/gradle/gradle/issues/17559 的限制,用户需要通过 Maven 依赖的形式引入 Metadata Repository 的 JSON 文件。
+参考 https://github.com/graalvm/native-build-tools/issues/572 。
+
+```groovy
+plugins {
+ id 'org.graalvm.buildtools.native' version '0.10.2'
+}
+
+dependencies {
+ implementation 'org.apache.shardingsphere.elasticjob:elasticjob-bootstrap:${elasticjob.version}'
+ implementation(group: 'org.graalvm.buildtools', name: 'graalvm-reachability-metadata', version: '0.10.2', classifier: 'repository', ext: 'zip')
+}
+
+graalvmNative {
+ metadataRepository {
+ enabled.set(false)
+ }
+}
+```
+
+## 对于 sbt 等不被 GraalVM Native Build Tools 支持的构建工具
+
+此类需求需要在 https://github.com/graalvm/native-build-tools 打开额外的 issue 并提供对应构建工具的 Plugin 实现。
+
+## 使用限制
+
+1. 用户无法在 GraalVM Native Image 使用 elasticJobType 为 SCRIPT 的 Job。参考 https://github.com/oracle/graal/issues/7390 。
+
+2. 使用者依然需要在 `src/main/resources/META-INF/native-image` 文件夹或 `src/test/resources/META-INF/native-image` 文件夹配置独立文件的 GraalVM Reachability Metadata。
+使用者可通过 GraalVM Native Build Tools 的 GraalVM Tracing Agent 来快速采集 GraalVM Reachability Metadata。
+
+3. ElasticJob 的 Spring 命名空间集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` 尚未在 GraalVM Native Image 下可用。
+
+4. ElasticJob 的 Spring Boot Starter 集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-boot-starter` 尚未在 GraalVM Native Image 下可用。
+
+## 贡献 GraalVM Reachability Metadata
+
+ElasticJob 对在 GraalVM Native Image 下的可用性的验证,是通过 GraalVM Native Build Tools 的 Maven Plugin 子项目来完成的。
+通过在 JVM 下运行单元测试,为单元测试打上 `junit-platform-unique-ids*` 标签,此后构建为 GraalVM Native Image 进行 nativeTest 来测试
+在 GraalVM Native Image 下的单元测试覆盖率。请贡献者不要使用 `io.kotest:kotest-runner-junit5-jvm:5.5.4` 等在 `test listener` mode 下
+failed to discover tests 的测试库。
+
+ElasticJob 定义了 `elasticjob-test-native` 的 Maven Module 用于为 native Test 提供小型的单元测试子集,
+此单元测试子集避免了使用 Mockito 等 native Test 下无法使用的第三方库。
+
+ElasticJob 定义了 `nativeTestInElasticJob` 的 Maven Profile 用于为 `elasticjob-test-native` 模块执行 nativeTest 。
+
+假设贡献者处于新的 Ubuntu 22.04.4 LTS 实例下,其可通过如下 bash 命令通过 SDKMAN! 管理 JDK 和工具链,
+并为 `elasticjob-test-native` 子模块执行 nativeTest。
+
+贡献者必须安装 Docker Engine 以执行 `testcontainers-java` 相关的单元测试。
+
+```bash
+sudo apt install unzip zip curl sed -y
+curl -s "https://get.sdkman.io" | bash
+source "$HOME/.sdkman/bin/sdkman-init.sh"
+sdk install java 22.0.2-graalce
+sdk use java 22.0.2-graalce
+sudo apt-get install build-essential zlib1g-dev -y
+
+git clone git@github.com:apache/shardingsphere-elasticjob.git
+cd ./shardingsphere-elasticjob/
+./mvnw -PnativeTestInElasticJob -T1C -e clean test
+```
+
+当贡献者发现缺少与 ElasticJob 无关的第三方库的 GraalVM Reachability Metadata 时,应当在
+https://github.com/oracle/graalvm-reachability-metadata 打开新的 issue, 并提交包含依赖的第三方库缺失的 GraalVM Reachability
+Metadata 的 PR。ElasticJob 在 `elasticjob-reachability-metadata` 子模块主动托管了部分第三方库的 GraalVM Reachability Metadata。
+
+如果 nativeTest 执行失败, 应为单元测试生成初步的 GraalVM Reachability Metadata,
+并手动调整 `elasticjob-reachability-metadata` 子模块的 classpath 的 `META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/` 文件夹下的内容以修复 nativeTest。
+如有需要,请使用 `org.junit.jupiter.api.condition.DisabledInNativeImage` 注解或 `org.graalvm.nativeimage.imagecode` 的
+System Property 屏蔽部分单元测试在 GraalVM Native Image 下运行。
+
+ElasticJob 定义了 `generateMetadata` 的 Maven Profile 用于在 GraalVM JIT Compiler 下携带 GraalVM Tracing Agent 执行单元测试,
+并在 `elasticjob-reachability-metadata` 子模块的 classpath 的 `META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/` 文件夹下,
+生成或覆盖已有的 GraalVM Reachability Metadata 文件。可通过如下 bash 命令简单处理此流程。
+贡献者仍可能需要手动调整具体的 JSON 条目,并适时调整 Maven Profile 和 GraalVM Tracing Agent 的 Filter 链。
+针对 `elasticjob-reachability-metadata` 子模块,
+手动增删改动的 JSON 条目应位于 `META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/` 文件夹下,
+而 `META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/` 中的条目仅应由 `generateMetadata` 的 Maven Profile 生成。
+
+以下命令仅为 `elasticjob-test-native` 生成 Conditional 形态的 GraalVM Reachability Metadata 的一个举例。
+生成的 GraalVM Reachability Metadata 位于 `elasticjob-reachability-metadata` 子模块下。
+
+对于测试类和测试文件独立使用的 GraalVM Reachability Metadata,贡献者应该放置到 `shardingsphere-test-native` 子模块的 classpath 的
+`META-INF/native-image/elasticjob-test-native-test-metadata/` 下。
+
+```bash
+git clone git@github.com:apache/shardingsphere.git
+cd ./shardingsphere/
+./mvnw -PgenerateMetadata -DskipNativeTests -e -T1C clean test native:metadata-copy
+```
diff --git a/docs/content/user-manual/configuration/graalvm-native-image.en.md b/docs/content/user-manual/configuration/graalvm-native-image.en.md
new file mode 100644
index 0000000000..23eda33816
--- /dev/null
+++ b/docs/content/user-manual/configuration/graalvm-native-image.en.md
@@ -0,0 +1,9 @@
++++
+title = "GraalVM Native Image Support"
+weight = 6
+chapter = true
++++
+
+## TODO
+
+Users can temporarily refer to the Chinese documentation corresponding to this page.
diff --git a/pom.xml b/pom.xml
index dee0a8d466..b6f8202b27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
test
distribution
+ reachability-metadata
@@ -126,6 +127,8 @@
1.0.0
3.4
1.10
+
+ 0.10.2
@@ -920,6 +923,100 @@
+
+ generateMetadata
+
+
+
+
+ maven-surefire-plugin
+
+
+ org.apache.shardingsphere.elasticjob.test.natived.**
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ ${native-maven-plugin.version}
+ true
+
+
+ true
+ Conditional
+
+
+ ${user.dir}/test/native/native-image-filter/user-code-filter.json
+ ${user.dir}/test/native/native-image-filter/extra-filter.json
+ true
+
+
+
+
+ main
+
+ false
+ ${user.dir}/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/
+
+
+
+
+
+ build-native
+
+ compile-no-fork
+
+ package
+
+
+ test-native
+
+ test
+
+ test
+
+
+
+
+
+
+
+
+ nativeTestInElasticJob
+
+
+
+
+ maven-surefire-plugin
+
+
+ org.apache.shardingsphere.elasticjob.test.natived.**
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ ${native-maven-plugin.version}
+ true
+
+ true
+
+
+
+ test-native
+
+ test
+
+ test
+
+
+
+
+
+
+
diff --git a/reachability-metadata/pom.xml b/reachability-metadata/pom.xml
new file mode 100644
index 0000000000..2d9cd037cf
--- /dev/null
+++ b/reachability-metadata/pom.xml
@@ -0,0 +1,12 @@
+
+
+ 4.0.0
+
+ org.apache.shardingsphere.elasticjob
+ elasticjob
+ 3.1.0-SNAPSHOT
+
+ elasticjob-reachability-metadata
+ ${project.artifactId}
+
+
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/reflect-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/reflect-config.json
new file mode 100644
index 0000000000..cb28c8e584
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/reflect-config.json
@@ -0,0 +1,7 @@
+[
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration",
+ "allPublicMethods":true
+}
+]
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/jni-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/jni-config.json
new file mode 100644
index 0000000000..32960f8ced
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/jni-config.json
@@ -0,0 +1,2 @@
+[
+]
\ No newline at end of file
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/predefined-classes-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/predefined-classes-config.json
new file mode 100644
index 0000000000..847895071f
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/predefined-classes-config.json
@@ -0,0 +1,7 @@
+[
+ {
+ "type":"agent-extracted",
+ "classes":[
+ ]
+ }
+]
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json
new file mode 100644
index 0000000000..fd2d4325f4
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json
@@ -0,0 +1,6 @@
+[
+ {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"},
+ "interfaces":["java.sql.Connection"]
+ }
+]
\ No newline at end of file
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json
new file mode 100644
index 0000000000..decaa1ec62
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json
@@ -0,0 +1,287 @@
+[
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"},
+ "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"com.google.common.util.concurrent.AbstractFuture",
+ "fields":[{"name":"listeners"}, {"name":"value"}, {"name":"waiters"}]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"com.google.common.util.concurrent.AbstractFuture$Waiter",
+ "fields":[{"name":"next"}, {"name":"thread"}]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.failover.FailoverListenerManager"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.reconcile.ReconcileService"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.item.JobItemExecutorFactory"},
+ "name":"org.apache.shardingsphere.elasticjob.dataflow.executor.DataflowJobExecutor"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.error.handler.JobErrorHandlerReloader"},
+ "name":"org.apache.shardingsphere.elasticjob.error.handler.normal.IgnoreJobErrorHandler",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.error.handler.JobErrorHandlerReloader"},
+ "name":"org.apache.shardingsphere.elasticjob.error.handler.normal.LogJobErrorHandler",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.error.handler.JobErrorHandlerReloader"},
+ "name":"org.apache.shardingsphere.elasticjob.error.handler.normal.ThrowJobErrorHandler",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "name":"org.apache.shardingsphere.elasticjob.http.executor.HttpJobExecutor"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.type.CPUUsageJobExecutorThreadPoolSizeProvider"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.type.SingleThreadJobExecutorThreadPoolSizeProvider"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "queryAllPublicMethods":true,
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setDescription","parameterTypes":["java.lang.String"] }, {"name":"setDisabled","parameterTypes":["boolean"] }, {"name":"setFailover","parameterTypes":["boolean"] }, {"name":"setJobExtraConfigurations","parameterTypes":["java.util.Collection"] }, {"name":"setJobName","parameterTypes":["java.lang.String"] }, {"name":"setJobParameter","parameterTypes":["java.lang.String"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "allDeclaredFields":true,
+ "methods":[{"name":"getCron","parameterTypes":[] }, {"name":"getDescription","parameterTypes":[] }, {"name":"getJobErrorHandlerType","parameterTypes":[] }, {"name":"getJobExecutorThreadPoolSizeProviderType","parameterTypes":[] }, {"name":"getJobExtraConfigurations","parameterTypes":[] }, {"name":"getJobListenerTypes","parameterTypes":[] }, {"name":"getJobName","parameterTypes":[] }, {"name":"getJobParameter","parameterTypes":[] }, {"name":"getJobShardingStrategyType","parameterTypes":[] }, {"name":"getLabel","parameterTypes":[] }, {"name":"getMaxTimeDiffSeconds","parameterTypes":[] }, {"name":"getProps","parameterTypes":[] }, {"name":"getReconcileIntervalMinutes","parameterTypes":[] }, {"name":"getShardingItemParameters","parameterTypes":[] }, {"name":"getShardingTotalCount","parameterTypes":[] }, {"name":"getTimeZone","parameterTypes":[] }, {"name":"isDisabled","parameterTypes":[] }, {"name":"isFailover","parameterTypes":[] }, {"name":"isMisfire","parameterTypes":[] }, {"name":"isMonitorExecution","parameterTypes":[] }, {"name":"isOverwrite","parameterTypes":[] }, {"name":"isStaticSharding","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.failover.FailoverListenerManager"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.reconcile.ReconcileService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJOBeanInfo"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJOCustomizer"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin",
+ "queryAllPublicMethods":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setCleanShutdown","parameterTypes":["boolean"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPluginBeanInfo"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPluginCustomizer"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceNode"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "allDeclaredFields":true,
+ "methods":[{"name":"getJobInstanceId","parameterTypes":[] }, {"name":"getLabels","parameterTypes":[] }, {"name":"getServerIp","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.SetUpFacade"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstanceBeanInfo"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstanceCustomizer"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setTracingStorageConfiguration","parameterTypes":["org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingStorageConfiguration"] }, {"name":"setType","parameterTypes":["java.lang.String"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfigurationConverter"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.exception.RegExceptionHandler"},
+ "name":"org.apache.shardingsphere.elasticjob.reg.zookeeper.exception.ZookeeperCuratorIgnoredExceptionProvider"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "name":"org.apache.shardingsphere.elasticjob.script.executor.ScriptJobExecutor"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.item.JobItemExecutorFactory"},
+ "name":"org.apache.shardingsphere.elasticjob.simple.executor.SimpleJobExecutor"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListener",
+ "queryAllDeclaredMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListener",
+ "queryAllDeclaredMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListenerFactory"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.storage.TracingStorageConverterFactory"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.DB2TracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.H2TracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.MySQLTracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.OracleTracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.PostgreSQLTracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.SQLServerTracingStorageDatabaseType"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.yaml.YamlDataSourceConfiguration",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSourceClassName","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Map"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO"},
+ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.yaml.YamlDataSourceConfigurationConverter"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter"},
+ "name":"org.apache.zookeeper.AddWatchMode"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter"},
+ "name":"org.apache.zookeeper.ClientCnxnSocketNIO",
+ "methods":[{"name":"","parameterTypes":["org.apache.zookeeper.client.ZKClientConfig"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter"},
+ "name":"org.apache.zookeeper.server.quorum.MultipleAddresses",
+ "methods":[{"name":"getReachableOrOne","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter"},
+ "name":"org.apache.zookeeper.server.quorum.QuorumPeer$QuorumServer",
+ "fields":[{"name":"addr"}]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "name":"sun.misc.Unsafe",
+ "allDeclaredFields":true
+}
+]
\ No newline at end of file
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json
new file mode 100644
index 0000000000..101e57e2fc
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json
@@ -0,0 +1,41 @@
+{
+ "resources":{
+ "includes":[{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.JobExecutorThreadPoolSizeProvider\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProviderFactory"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProvider\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.exception.RegExceptionHandler"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.reg.exception.IgnoredExceptionProvider\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.error.handler.JobErrorHandler\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.item.JobItemExecutorFactory"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.item.type.ClassedJobItemExecutor\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.item.type.TypedJobItemExecutor\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListenerFactory\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.storage.TracingStorageConverterFactory"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.tracing.storage.TracingStorageConfigurationConverter\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.yaml.YamlConfigurationConverter\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+ "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.TracingStorageDatabaseType\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.sql.SQLPropertiesFactory"},
+ "pattern":"\\QMETA-INF/sql/H2.properties\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "pattern":"\\Qorg/quartz/core/quartz-build.properties\\E"
+ }]},
+ "bundles":[]
+}
\ No newline at end of file
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/serialization-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/serialization-config.json
new file mode 100644
index 0000000000..d0304f2a1c
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/serialization-config.json
@@ -0,0 +1,8 @@
+{
+ "types":[
+ ],
+ "lambdaCapturingTypes":[
+ ],
+ "proxies":[
+ ]
+}
\ No newline at end of file
diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.zookeeper/zookeeper/3.9.2/reflect-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.zookeeper/zookeeper/3.9.2/reflect-config.json
new file mode 100644
index 0000000000..a6e52201ca
--- /dev/null
+++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.zookeeper/zookeeper/3.9.2/reflect-config.json
@@ -0,0 +1,56 @@
+[
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.ZooKeeper"},
+ "name":"org.apache.zookeeper.ClientCnxnSocketNIO",
+ "methods":[{"name":"","parameterTypes":["org.apache.zookeeper.client.ZKClientConfig"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.metrics.impl.MetricsProviderBootstrap"},
+ "name":"org.apache.zookeeper.metrics.impl.DefaultMetricsProvider",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.quorum.QuorumPeerConfig"},
+ "name":"org.apache.zookeeper.metrics.impl.DefaultMetricsProvider"
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ServerCnxnFactory"},
+ "name":"org.apache.zookeeper.server.ConnectionBean",
+ "queryAllPublicConstructors":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ServerCnxnFactory"},
+ "name":"org.apache.zookeeper.server.ConnectionMXBean",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ZooKeeperServer"},
+ "name":"org.apache.zookeeper.server.DataTreeBean",
+ "queryAllPublicConstructors":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ZooKeeperServer"},
+ "name":"org.apache.zookeeper.server.DataTreeMXBean",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ServerCnxnFactory"},
+ "name":"org.apache.zookeeper.server.NIOServerCnxnFactory",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ZooKeeperServer"},
+ "name":"org.apache.zookeeper.server.ZooKeeperServerBean",
+ "queryAllPublicConstructors":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.ZooKeeperServer"},
+ "name":"org.apache.zookeeper.server.ZooKeeperServerMXBean",
+ "queryAllPublicMethods":true
+},
+{
+ "condition":{"typeReachable":"org.apache.zookeeper.server.watch.WatchManagerFactory"},
+ "name":"org.apache.zookeeper.server.watch.WatchManager",
+ "methods":[{"name":"","parameterTypes":[] }]
+}
+]
diff --git a/spring/core/pom.xml b/spring/core/pom.xml
index 1d59320696..dbc3b8c1b5 100644
--- a/spring/core/pom.xml
+++ b/spring/core/pom.xml
@@ -42,15 +42,18 @@
org.springframework
spring-context
+ provided
org.springframework
spring-context-support
+ provided
org.springframework
spring-test
+ test
diff --git a/spring/namespace/pom.xml b/spring/namespace/pom.xml
index 62d842f237..83a3a8ae40 100644
--- a/spring/namespace/pom.xml
+++ b/spring/namespace/pom.xml
@@ -62,10 +62,12 @@
org.springframework
spring-context
+ provided
org.springframework
spring-context-support
+ provided
@@ -75,6 +77,7 @@
org.springframework
spring-test
+ test
com.h2database
diff --git a/test/native/native-image-filter/extra-filter.json b/test/native/native-image-filter/extra-filter.json
new file mode 100644
index 0000000000..62800a1b20
--- /dev/null
+++ b/test/native/native-image-filter/extra-filter.json
@@ -0,0 +1,14 @@
+{
+ "rules": [
+ {"includeClasses": "**"},
+
+ {"excludeClasses": "com.zaxxer.hikari.**"},
+ {"excludeClasses": "java.**"},
+ {"includeClasses": "java.util.Properties"},
+ {"excludeClasses": "org.quartz.**"},
+
+ {"excludeClasses": "org.apache.shardingsphere.elasticjob.test.natived.**"}
+ ],
+ "regexRules": [
+ ]
+}
diff --git a/test/native/native-image-filter/user-code-filter.json b/test/native/native-image-filter/user-code-filter.json
new file mode 100644
index 0000000000..926a991968
--- /dev/null
+++ b/test/native/native-image-filter/user-code-filter.json
@@ -0,0 +1,7 @@
+{
+ "rules": [
+ {"excludeClasses": "**"},
+ {"includeClasses": "org.apache.shardingsphere.elasticjob.**"},
+ {"excludeClasses": "org.apache.shardingsphere.elasticjob.test.natived.**"}
+ ]
+}
diff --git a/test/native/pom.xml b/test/native/pom.xml
new file mode 100644
index 0000000000..1becb88eef
--- /dev/null
+++ b/test/native/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ org.apache.shardingsphere.elasticjob
+ elasticjob-test
+ 3.1.0-SNAPSHOT
+
+ elasticjob-test-native
+ ${project.artifactId}
+
+
+ true
+
+
+
+
+ org.apache.shardingsphere.elasticjob
+ elasticjob-bootstrap
+ ${project.version}
+ test
+
+
+
+ org.awaitility
+ awaitility
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+ org.apache.curator
+ curator-test
+ test
+
+
+
+
+
+
+ org.graalvm.buildtools
+ native-maven-plugin
+ ${native-maven-plugin.version}
+
+
+
+
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java
new file mode 100644
index 0000000000..42d6e34f99
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.curator.CuratorZookeeperClient;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.apache.curator.test.TestingServer;
+import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
+import org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap;
+import org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap;
+import org.apache.shardingsphere.elasticjob.dataflow.props.DataflowJobProperties;
+import org.apache.shardingsphere.elasticjob.http.props.HttpJobProperties;
+import org.apache.shardingsphere.elasticjob.kernel.tracing.config.TracingConfiguration;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration;
+import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter;
+import org.apache.shardingsphere.elasticjob.script.props.ScriptJobProperties;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow.JavaDataflowJob;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.job.simple.JavaSimpleJob;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.time.Duration;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+class JavaTest {
+
+ private static TestingServer testingServer;
+
+ private static CoordinatorRegistryCenter regCenter;
+
+ private static TracingConfiguration tracingConfig;
+
+ @BeforeAll
+ static void beforeAll() throws Exception {
+ testingServer = new TestingServer();
+ try (
+ CuratorZookeeperClient client = new CuratorZookeeperClient(testingServer.getConnectString(),
+ 60 * 1000, 500, null,
+ new ExponentialBackoffRetry(500, 3, 500 * 3))) {
+ client.start();
+ Awaitility.await().atMost(Duration.ofMillis(500 * 60)).until(client::isConnected);
+ }
+ regCenter = new ZookeeperRegistryCenter(new ZookeeperConfiguration(testingServer.getConnectString(), "elasticjob-test-native-java"));
+ regCenter.init();
+ HikariConfig config = new HikariConfig();
+ config.setDriverClassName("org.h2.Driver");
+ config.setJdbcUrl("jdbc:h2:mem:job_event_storage");
+ config.setUsername("sa");
+ config.setPassword("");
+ tracingConfig = new TracingConfiguration<>("RDB", new HikariDataSource(config));
+ }
+
+ @AfterAll
+ static void afterAll() throws IOException {
+ regCenter.close();
+ testingServer.close();
+ }
+
+ @Test
+ void testHttpJob() {
+ ScheduleJobBootstrap jobBootstrap = new ScheduleJobBootstrap(regCenter, "HTTP",
+ JobConfiguration.newBuilder("testJavaHttpJob", 3)
+ .setProperty(HttpJobProperties.URI_KEY, "https://www.apache.org")
+ .setProperty(HttpJobProperties.METHOD_KEY, "GET")
+ .cron("0/5 * * * * ?")
+ .shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+ .addExtraConfigurations(tracingConfig)
+ .build());
+ assertDoesNotThrow(() -> {
+ jobBootstrap.schedule();
+ jobBootstrap.shutdown();
+ });
+ }
+
+ @Test
+ void testSimpleJob() {
+ ScheduleJobBootstrap jobBootstrap = new ScheduleJobBootstrap(regCenter, new JavaSimpleJob(),
+ JobConfiguration.newBuilder("testJavaSimpleJob", 3)
+ .cron("0/5 * * * * ?")
+ .shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+ .addExtraConfigurations(tracingConfig)
+ .build());
+ assertDoesNotThrow(() -> {
+ jobBootstrap.schedule();
+ jobBootstrap.shutdown();
+ });
+ }
+
+ @Test
+ void testDataflowJob() {
+ ScheduleJobBootstrap jobBootstrap = new ScheduleJobBootstrap(regCenter, new JavaDataflowJob(),
+ JobConfiguration.newBuilder("testJavaDataflowElasticJob", 3)
+ .cron("0/5 * * * * ?")
+ .shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+ .setProperty(DataflowJobProperties.STREAM_PROCESS_KEY, Boolean.TRUE.toString())
+ .addExtraConfigurations(tracingConfig)
+ .build());
+ assertDoesNotThrow(() -> {
+ jobBootstrap.schedule();
+ jobBootstrap.shutdown();
+ });
+ }
+
+ @Test
+ void testOneOffJob() {
+ OneOffJobBootstrap jobBootstrap = new OneOffJobBootstrap(regCenter, new JavaSimpleJob(),
+ JobConfiguration.newBuilder("testJavaOneOffSimpleJob", 3)
+ .shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+ .addExtraConfigurations(tracingConfig)
+ .build());
+ assertDoesNotThrow(() -> {
+ jobBootstrap.execute();
+ jobBootstrap.shutdown();
+ });
+ }
+
+ @Test
+ @EnabledOnOs(OS.LINUX)
+ void testScriptJob() {
+ ScheduleJobBootstrap jobBootstrap = new ScheduleJobBootstrap(regCenter, "SCRIPT",
+ JobConfiguration.newBuilder("scriptElasticJob", 3)
+ .cron("0/5 * * * * ?")
+ .setProperty(ScriptJobProperties.SCRIPT_KEY, Paths.get("src/test/resources/script/demo.sh").toString())
+ .addExtraConfigurations(tracingConfig)
+ .build());
+ assertDoesNotThrow(() -> {
+ jobBootstrap.schedule();
+ jobBootstrap.shutdown();
+ });
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/entity/Foo.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/entity/Foo.java
new file mode 100644
index 0000000000..7fb818cd65
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/entity/Foo.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived.commons.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+@Getter
+@ToString
+@AllArgsConstructor
+public final class Foo implements Serializable {
+
+ private static final long serialVersionUID = 2706842871078949451L;
+
+ private final long id;
+
+ private final String location;
+
+ @Setter
+ private Status status;
+
+ public enum Status {
+ TODO,
+ COMPLETED
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/JavaDataflowJob.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/JavaDataflowJob.java
new file mode 100644
index 0000000000..7c87dffacc
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/JavaDataflowJob.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow;
+
+import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext;
+import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.FooRepository;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.FooRepositoryFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+public class JavaDataflowJob implements DataflowJob {
+
+ private final FooRepository fooRepository = FooRepositoryFactory.getFOO_REPOSITORY();
+
+ @Override
+ public List fetchData(final ShardingContext shardingContext) {
+ System.out.printf(
+ "Item: %s | Time: %s | Thread: %s | %s%n",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "DATAFLOW FETCH");
+ return fooRepository.findTodoData(shardingContext.getShardingParameter(), 10);
+ }
+
+ @Override
+ public void processData(final ShardingContext shardingContext, final List data) {
+ System.out.printf(
+ "Item: %s | Time: %s | Thread: %s | %s%n",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "DATAFLOW PROCESS");
+ data.stream().mapToLong(Foo::getId).forEach(fooRepository::setCompleted);
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/JavaSimpleJob.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/JavaSimpleJob.java
new file mode 100644
index 0000000000..0932a700bc
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/JavaSimpleJob.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived.commons.job.simple;
+
+import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext;
+import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.FooRepository;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.FooRepositoryFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+public class JavaSimpleJob implements SimpleJob {
+
+ private final FooRepository fooRepository = FooRepositoryFactory.getFOO_REPOSITORY();
+
+ @Override
+ public void execute(final ShardingContext shardingContext) {
+ System.out.printf(
+ "Item: %s | Time: %s | Thread: %s | %s%n",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "SIMPLE");
+ List data = fooRepository.findTodoData(shardingContext.getShardingParameter(), 10);
+ data.stream().mapToLong(Foo::getId).forEach(fooRepository::setCompleted);
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepository.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepository.java
new file mode 100644
index 0000000000..e6abaf1b10
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepository.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived.commons.repository;
+
+import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.LongStream;
+
+public class FooRepository {
+
+ private final Map data = new ConcurrentHashMap<>(300, 1);
+
+ public FooRepository() {
+ addData(0L, 100L, "Norddorf");
+ addData(100L, 200L, "Bordeaux");
+ addData(200L, 300L, "Somerset");
+ }
+
+ private void addData(final long idFrom, final long idTo, final String location) {
+ LongStream.range(idFrom, idTo)
+ .forEachOrdered(i -> data.put(i, new Foo(i, location, Foo.Status.TODO)));
+ }
+
+ /**
+ * Find todoData.
+ * @param location location
+ * @param limit limit
+ * @return An ordered collection, where the user has precise control over where in the list each element is inserted.
+ */
+ public List findTodoData(final String location, final int limit) {
+ List result = new ArrayList<>(limit);
+ int count = 0;
+ for (Map.Entry each : data.entrySet()) {
+ Foo foo = each.getValue();
+ if (foo.getLocation().equals(location) && foo.getStatus() == Foo.Status.TODO) {
+ result.add(foo);
+ count++;
+ if (count == limit) {
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set completed.
+ * @param id id
+ */
+ public void setCompleted(final long id) {
+ data.get(id).setStatus(Foo.Status.COMPLETED);
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepositoryFactory.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepositoryFactory.java
new file mode 100644
index 0000000000..8ce70c48f6
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/FooRepositoryFactory.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.test.natived.commons.repository;
+
+import lombok.Getter;
+
+public final class FooRepositoryFactory {
+
+ @Getter
+ private static final FooRepository FOO_REPOSITORY = new FooRepository();
+
+}
diff --git a/test/native/src/test/resources/script/demo.sh b/test/native/src/test/resources/script/demo.sh
new file mode 100644
index 0000000000..a3f5b00278
--- /dev/null
+++ b/test/native/src/test/resources/script/demo.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# shellcheck disable=SC2048
+# shellcheck disable=SC2086
+echo Sharding Context: $*
diff --git a/test/pom.xml b/test/pom.xml
index 5c11d880af..4d6d5e326f 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -30,5 +30,6 @@
e2e
util
+ native