This is an automated email from the ASF dual-hosted git repository.

sunnianjun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git


The following commit(s) were added to refs/heads/master by this push:
     new 8bb5fa88d Provides built-in GraalVM Reachability Metadata and 
nativeTest on Elasticjob Bootstrap (#2268)
8bb5fa88d is described below

commit 8bb5fa88d4435628d41f0a9b74c1503f521405ad
Author: Ling Hengqian <[email protected]>
AuthorDate: Mon Jul 29 15:40:29 2024 +0800

    Provides built-in GraalVM Reachability Metadata and nativeTest on 
Elasticjob Bootstrap (#2268)
---
 .github/workflows/graalvm.yml                      |  47 ++++
 bootstrap/pom.xml                                  |   5 +
 .../configuration/graalvm-native-image.cn.md       | 169 ++++++++++++++
 .../configuration/graalvm-native-image.en.md       | 173 ++++++++++++++
 pom.xml                                            | 101 +++++++-
 {test => reachability-metadata}/pom.xml            |   9 +-
 .../reflect-config.json                            |   7 +
 .../resource-config.json                           |  11 +
 .../jni-config.json                                |   2 +
 .../predefined-classes-config.json                 |   7 +
 .../proxy-config.json                              |   6 +
 .../reflect-config.json                            | 253 +++++++++++++++++++++
 .../resource-config.json                           |  41 ++++
 .../serialization-config.json                      |   8 +
 .../zookeeper/3.9.2/reflect-config.json            |  56 +++++
 spring/core/pom.xml                                |   3 +
 spring/namespace/pom.xml                           |   3 +
 test/native/native-image-filter/extra-filter.json  |  17 ++
 .../native-image-filter/user-code-filter.json      |   7 +
 {spring/core => test/native}/pom.xml               |  43 ++--
 .../elasticjob/test/natived/JavaTest.java          | 168 ++++++++++++++
 .../test/natived/commons/entity/Foo.java           |  45 ++++
 .../commons/job/dataflow/JavaDataflowJob.java      |  55 +++++
 .../natived/commons/job/simple/JavaSimpleJob.java  |  45 ++++
 .../natived/commons/repository/FooRepository.java  |  72 ++++++
 .../commons/repository/FooRepositoryFactory.java   |  27 +++
 test/native/src/test/resources/script/demo.sh      |  21 ++
 test/pom.xml                                       |   1 +
 28 files changed, 1378 insertions(+), 24 deletions(-)

diff --git a/.github/workflows/graalvm.yml b/.github/workflows/graalvm.yml
new file mode 100644
index 000000000..fcff1f14e
--- /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 75ae79034..4606a518d 100644
--- a/bootstrap/pom.xml
+++ b/bootstrap/pom.xml
@@ -62,6 +62,11 @@
             <artifactId>elasticjob-tracing-rdb</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.shardingsphere.elasticjob</groupId>
+            <artifactId>elasticjob-reachability-metadata</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         
         <dependency>
             <groupId>org.apache.shardingsphere.elasticjob</groupId>
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 000000000..8a892fa37
--- /dev/null
+++ b/docs/content/user-manual/configuration/graalvm-native-image.cn.md
@@ -0,0 +1,169 @@
++++
+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#graalhttps://sdkman.io/jdks#nikhttps://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 来构建 ElasticJob 的 GraalVM 
Native Image 产物。
+ElasticJob 不为已停止维护的 GraalVM CE 版本设置 CI。
+
+## 使用 ElasticJob 的 Java API
+
+### Maven 生态
+
+使用者需要主动使用 GraalVM Reachability Metadata 中央仓库。
+如下配置可供参考,以配置项目额外的 Maven Profiles,以 GraalVM Native Build Tools 的文档为准。
+
+```xml
+<project>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shardingsphere.elasticjob</groupId>
+            <artifactId>elasticjob-bootstrap</artifactId>
+            <version>${elasticjob.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.graalvm.buildtools</groupId>
+                <artifactId>native-maven-plugin</artifactId>
+                <version>0.10.2</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <id>build-native</id>
+                        <goals>
+                            <goal>compile-no-fork</goal>
+                        </goals>
+                        <phase>package</phase>
+                    </execution>
+                    <execution>
+                        <id>test-native</id>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <phase>test</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
+```
+
+### 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. 使用者依然需要在 `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。
+
+2. 对于在 Linux 系统下执行 `elasticJobType` 为 `SCRIPT` 的 
`org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap`,
+若 `script.command.line` 设置为构建 GraalVM Native Image 时, 私有项目的 classpath 下的某个 
`.sh` 文件在 GraalVM Native Image 下的相对路径,
+则此 `.sh` 文件至少提前设置 `rwxr-xr-x` 的 POSIX 文件权限。
+因为 `com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystem` 显然不支持 
`java.nio.file.attribute.PosixFileAttributeView`。
+
+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 [email protected]: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 [email protected]: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 000000000..5b9018c8c
--- /dev/null
+++ b/docs/content/user-manual/configuration/graalvm-native-image.en.md
@@ -0,0 +1,173 @@
++++
+title = "GraalVM Native Image"
+weight = 6
+chapter = true
++++
+
+## Background information
+
+ElasticJob has been verified for availability under GraalVM Native Image.
+
+To build a GraalVM Native Image with the Maven dependency 
`org.apache.shardingsphere.elasticjob:elasticjob-bootstrap:${elasticjob.version}`,
+you need to use GraalVM Native Build Tools.
+
+GraalVM Native Build Tools provides Maven Plugin and Gradle Plugin to simplify 
the long-winded shell commands of GraalVM CE's `native-image` command line tool.
+
+ElasticJob requires the following or higher versions of `GraalVM CE` to build 
the GraalVM Native Image. Users can quickly switch JDKs through `SDKMAN!`. 
+This also applies to downstream distributions of `GraalVM CE` such as 
https://sdkman.io/jdks#graal, https://sdkman.io/jdks#nik and 
https://sdkman.io/jdks#mandrel.
+
+- GraalVM CE For JDK 22.0.2, corresponding to `22.0.2-graalce` of SDKMAN!
+
+Users can still use old versions of GraalVM CE such as `21.0.2-graalce` on 
SDKMAN! to build ElasticJob's GraalVM Native Image product.
+ElasticJob does not set CI for GraalVM CE versions that have stopped 
maintenance.
+
+## Using ElasticJob's Java API
+
+### Maven Ecosystem
+
+Users need to actively use the GraalVM Reachability Metadata Central 
Repository.
+The following configuration is for reference. To configure additional Maven 
Profiles for the project, 
+refer to the documentation of GraalVM Native Build Tools.
+
+```xml
+<project>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shardingsphere.elasticjob</groupId>
+            <artifactId>elasticjob-bootstrap</artifactId>
+            <version>${elasticjob.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.graalvm.buildtools</groupId>
+                <artifactId>native-maven-plugin</artifactId>
+                <version>0.10.2</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <id>build-native</id>
+                        <goals>
+                            <goal>compile-no-fork</goal>
+                        </goals>
+                        <phase>package</phase>
+                    </execution>
+                    <execution>
+                        <id>test-native</id>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <phase>test</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
+```
+
+### Gradle Ecosystem
+
+Users need to actively use the GraalVM Reachability Metadata Central 
Repository.
+The following configuration is for reference. To configure additional Gradle 
Tasks for the project, refer to the documentation of GraalVM Native Build Tools.
+Due to the limitations of https://github.com/gradle/gradle/issues/17559, users 
need to introduce the Metadata Repository JSON file in the form of Maven 
dependencies.
+Refer to 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)
+   }
+}
+```
+
+## For build tools such as sbt that are not supported by GraalVM Native Build 
Tools
+
+Such requirements require opening additional issues at 
https://github.com/graalvm/native-build-tools and providing plugin 
implementations for the corresponding build tools.
+
+## Usage restrictions
+
+1. Users still need to configure GraalVM Reachability Metadata in separate 
files in the `src/main/resources/META-INF/native-image` folder or the 
`src/test/resources/META-INF/native-image` folder.
+Users can quickly collect GraalVM Reachability Metadata through the GraalVM 
Tracing Agent of GraalVM Native Build Tools.
+
+2. For 
`org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap` with 
`elasticJobType` as `SCRIPT` under Linux, 
+if `script.command.line` is set to the relative path of a `.sh` file in the 
private project's classpath under the GraalVM Native Image when building the 
GraalVM Native Image, 
+then the `.sh` file must at least have the POSIX file permission of 
`rwxr-xr-x` set in advance. 
+This is because 
`com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystem` obviously 
does not support `java.nio.file.attribute.PosixFileAttributeView`.
+
+3. The Spring namespace integration module 
`org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` of 
ElasticJob is not yet available under GraalVM Native Image.
+
+4. The Spring Boot Starter integration module 
`org.apache.shardingsphere.elasticjob:elasticjob-spring-boot-starter` for 
ElasticJob is not yet available under GraalVM Native Image.
+
+## Contribute GraalVM Reachability Metadata
+
+ElasticJob's usability verification under GraalVM Native Image is done by the 
Maven Plugin subproject of GraalVM Native Build Tools.
+
+Unit test coverage under GraalVM Native Image is tested by running unit tests 
under JVM, 
+tagging unit tests with `junit-platform-unique-ids*`, and then building 
GraalVM Native Image for nativeTest. 
+Contributors are requested not to use test libraries such as 
`io.kotest:kotest-runner-junit5-jvm:5.5.4` that failed to discover tests in 
`test listener` mode.
+
+ElasticJob defines the `elasticjob-test-native` Maven Module to provide a 
small subset of unit tests for native Test,
+which avoids the use of third-party libraries such as Mockito that cannot be 
used under native Test.
+
+ElasticJob defines the `nativeTestInElasticJob` Maven profile to execute 
nativeTest for the `elasticjob-test-native` module.
+
+Assuming the contributor is on a fresh Ubuntu 22.04.4 LTS instance, he can use 
SDKMAN! to manage JDK and toolchains with the following bash command,
+and execute nativeTest for the `elasticjob-test-native` submodule.
+
+Contributors must install Docker Engine to execute the `testcontainers-java` 
related unit tests.
+
+```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 [email protected]:apache/shardingsphere-elasticjob.git
+cd ./shardingsphere-elasticjob/
+./mvnw -PnativeTestInElasticJob -T1C -e clean test
+```
+
+When contributors find that GraalVM Reachability Metadata for third-party 
libraries not related to ElasticJob is missing, 
+they should open a new issue at 
https://github.com/oracle/graalvm-reachability-metadata, 
+and submit a PR with missing GraalVM Reachability Metadata for dependent 
third-party libraries. 
+ElasticJob proactively hosts GraalVM Reachability Metadata for some 
third-party libraries in the `elasticjob-reachability-metadata` submodule.
+
+If nativeTest fails, generate preliminary GraalVM Reachability Metadata for 
unit tests, 
+and manually adjust the contents of the 
`META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/`
 folder in the classpath of the `elasticjob-reachability-metadata` submodule to 
fix nativeTest.
+If necessary, 
+use the `org.junit.jupiter.api.condition.DisabledInNativeImage` annotation or 
the `org.graalvm.nativeimage.imagecode` System Property to shield some unit 
tests from running under the GraalVM Native Image.
+
+ElasticJob defines the `generateMetadata` Maven Profile to execute unit tests 
with the GraalVM Tracing Agent under the GraalVM JIT Compiler,
+and generates or overwrites the existing GraalVM Reachability Metadata file in 
the 
`META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/`
 folder in the classpath of the `elasticjob-reachability-metadata` submodule. 
+This process can be easily handled by the following bash command. 
+Contributors may still need to manually adjust specific JSON entries and 
adjust the filter chain of the Maven Profile and GraalVM Tracing Agent as 
appropriate. 
+For the `elasticjob-reachability-metadata` submodule,
+manually added, deleted, and modified JSON entries should be located in the 
`META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/`
 folder,
+while the entries in 
`META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/`
 should only be generated by the `generateMetadata` Maven Profile.
+
+The following command is just an example of generating Conditional GraalVM 
Reachability Metadata for `elasticjob-test-native`.
+The generated GraalVM Reachability Metadata is located in the 
`elasticjob-reachability-metadata` submodule.
+
+For GraalVM Reachability Metadata used independently by test classes and test 
files, 
+contributors should place it in the classpath of the 
shardingsphere-test-native submodule under 
`META-INF/native-image/elasticjob-test-native-test-metadata/`.
+
+```bash
+git clone [email protected]:apache/shardingsphere.git
+cd ./shardingsphere/
+./mvnw -PgenerateMetadata -DskipNativeTests -e -T1C clean test 
native:metadata-copy
+```
diff --git a/pom.xml b/pom.xml
index dee0a8d46..15a3aa9ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
         <module>test</module>
         
         <module>distribution</module>
+        <module>reachability-metadata</module>
     </modules>
     
     <properties>
@@ -83,7 +84,7 @@
         
         <lombok.version>1.18.30</lombok.version>
         
-        <junit.version>5.10.0</junit.version>
+        <junit.version>5.10.3</junit.version>
         <hamcrest.version>2.2</hamcrest.version>
         <mockito.version>4.11.0</mockito.version>
         <awaitility.version>4.2.0</awaitility.version>
@@ -126,6 +127,8 @@
         <lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
         <maven-plugin-plugin.version>3.4</maven-plugin-plugin.version>
         <checksum-maven-plugin.version>1.10</checksum-maven-plugin.version>
+        
+        <native-maven-plugin.version>0.10.2</native-maven-plugin.version>
     </properties>
     
     <dependencyManagement>
@@ -815,6 +818,8 @@
                                     <exclude>**/package-lock.json</exclude>
                                     <!-- example files -->
                                     <exclude>/examples/**</exclude>
+                                    <!-- GraalVM Reachability Metadata is not 
in JSON5 format.-->
+                                    
<exclude>**/META-INF/native-image/**/*.json</exclude>
                                     <!-- to be determined -->
                                     <exclude>**/AdminLTE/**</exclude>
                                     <exclude>**/bootstrap/**</exclude>
@@ -920,6 +925,100 @@
                 </plugins>
             </build>
         </profile>
+        <profile>
+            <id>generateMetadata</id>
+            <build>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <artifactId>maven-surefire-plugin</artifactId>
+                            <configuration>
+                                <includes>
+                                    
<include>org.apache.shardingsphere.elasticjob.test.natived.**</include>
+                                </includes>
+                            </configuration>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.graalvm.buildtools</groupId>
+                            <artifactId>native-maven-plugin</artifactId>
+                            <version>${native-maven-plugin.version}</version>
+                            <extensions>true</extensions>
+                            <configuration>
+                                <agent>
+                                    <enabled>true</enabled>
+                                    <defaultMode>Conditional</defaultMode>
+                                    <modes>
+                                        <conditional>
+                                            
<userCodeFilterPath>${user.dir}/test/native/native-image-filter/user-code-filter.json</userCodeFilterPath>
+                                            
<extraFilterPath>${user.dir}/test/native/native-image-filter/extra-filter.json</extraFilterPath>
+                                            <parallel>true</parallel>
+                                        </conditional>
+                                    </modes>
+                                    <metadataCopy>
+                                        <disabledStages>
+                                            <stage>main</stage>
+                                        </disabledStages>
+                                        <merge>false</merge>
+                                        
<outputDirectory>${user.dir}/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/</outputDirectory>
+                                    </metadataCopy>
+                                </agent>
+                            </configuration>
+                            <executions>
+                                <execution>
+                                    <id>build-native</id>
+                                    <goals>
+                                        <goal>compile-no-fork</goal>
+                                    </goals>
+                                    <phase>package</phase>
+                                </execution>
+                                <execution>
+                                    <id>test-native</id>
+                                    <goals>
+                                        <goal>test</goal>
+                                    </goals>
+                                    <phase>test</phase>
+                                </execution>
+                            </executions>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+            </build>
+        </profile>
+        <profile>
+            <id>nativeTestInElasticJob</id>
+            <build>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <artifactId>maven-surefire-plugin</artifactId>
+                            <configuration>
+                                <includes>
+                                    
<include>org.apache.shardingsphere.elasticjob.test.natived.**</include>
+                                </includes>
+                            </configuration>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.graalvm.buildtools</groupId>
+                            <artifactId>native-maven-plugin</artifactId>
+                            <version>${native-maven-plugin.version}</version>
+                            <extensions>true</extensions>
+                            <configuration>
+                                <quickBuild>true</quickBuild>
+                            </configuration>
+                            <executions>
+                                <execution>
+                                    <id>test-native</id>
+                                    <goals>
+                                        <goal>test</goal>
+                                    </goals>
+                                    <phase>test</phase>
+                                </execution>
+                            </executions>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+            </build>
+        </profile>
     </profiles>
     
 </project>
diff --git a/test/pom.xml b/reachability-metadata/pom.xml
similarity index 88%
copy from test/pom.xml
copy to reachability-metadata/pom.xml
index 5c11d880a..29ddf18b6 100644
--- a/test/pom.xml
+++ b/reachability-metadata/pom.xml
@@ -8,7 +8,7 @@
   ~ 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.
@@ -23,12 +23,7 @@
         <artifactId>elasticjob</artifactId>
         <version>3.1.0-SNAPSHOT</version>
     </parent>
-    <artifactId>elasticjob-test</artifactId>
-    <packaging>pom</packaging>
+    <artifactId>elasticjob-reachability-metadata</artifactId>
     <name>${project.artifactId}</name>
     
-    <modules>
-        <module>e2e</module>
-        <module>util</module>
-    </modules>
 </project>
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 000000000..cb28c8e58
--- /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/elasticjob-reachability-metadata/resource-config.json
 
b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/resource-config.json
new file mode 100644
index 000000000..8003abbbb
--- /dev/null
+++ 
b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/elasticjob-reachability-metadata/resource-config.json
@@ -0,0 +1,11 @@
+{
+  "resources":{
+  "includes":[{
+    
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"},
+    
"pattern":".*META-INF/services/org\\.apache\\.shardingsphere\\.elasticjob\\..+"
+  }, {
+    
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.sql.SQLPropertiesFactory"},
+    "pattern":".*META-INF/sql/.+\\.properties$"
+  }]},
+  "bundles":[]
+}
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 000000000..32960f8ce
--- /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 000000000..847895071
--- /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 000000000..fd2d4325f
--- /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 000000000..b934e8520
--- /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,253 @@
+[
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"},
+  "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+  "name":"java.util.Properties",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+  "name":"java.util.Properties",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.failover.FailoverListenerManager"},
+  "name":"java.util.Properties",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.reconcile.ReconcileService"},
+  "name":"java.util.Properties",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+  "name":"java.util.Properties",
+  "methods":[{"name":"<init>","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":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.error.handler.JobErrorHandlerReloader"},
+  
"name":"org.apache.shardingsphere.elasticjob.error.handler.normal.LogJobErrorHandler",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.error.handler.JobErrorHandlerReloader"},
+  
"name":"org.apache.shardingsphere.elasticjob.error.handler.normal.ThrowJobErrorHandler",
+  "methods":[{"name":"<init>","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":"<init>","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" [...]
+},
+{
+  
"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":[ [...]
+},
+{
+  
"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":"<init>","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":"<init>","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":"<init>","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"
+}
+]
\ 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 000000000..101e57e2f
--- /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 000000000..d0304f2a1
--- /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 000000000..a6e52201c
--- /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":"<init>","parameterTypes":["org.apache.zookeeper.client.ZKClientConfig"]
 }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.zookeeper.metrics.impl.MetricsProviderBootstrap"},
+  "name":"org.apache.zookeeper.metrics.impl.DefaultMetricsProvider",
+  "methods":[{"name":"<init>","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":"<init>","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":"<init>","parameterTypes":[] }]
+}
+]
diff --git a/spring/core/pom.xml b/spring/core/pom.xml
index 1d5932069..dbc3b8c1b 100644
--- a/spring/core/pom.xml
+++ b/spring/core/pom.xml
@@ -42,15 +42,18 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context-support</artifactId>
+            <scope>provided</scope>
         </dependency>
         
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 </project>
diff --git a/spring/namespace/pom.xml b/spring/namespace/pom.xml
index 62d842f23..83a3a8ae4 100644
--- a/spring/namespace/pom.xml
+++ b/spring/namespace/pom.xml
@@ -62,10 +62,12 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context-support</artifactId>
+            <scope>provided</scope>
         </dependency>
         
         <dependency>
@@ -75,6 +77,7 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
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 000000000..9e706a39d
--- /dev/null
+++ b/test/native/native-image-filter/extra-filter.json
@@ -0,0 +1,17 @@
+{
+  "rules": [
+    {"includeClasses": "**"},
+
+    {"excludeClasses": "com.google.common.util.concurrent.**"},
+    {"excludeClasses": "com.zaxxer.hikari.**"},
+    {"excludeClasses": "java.**"},
+    {"includeClasses": "java.util.Properties"},
+    {"excludeClasses": "org.apache.zookeeper.**"},
+    {"excludeClasses": "org.quartz.**"},
+    {"excludeClasses": "sun.misc.**"},
+
+    {"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 000000000..926a99196
--- /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/spring/core/pom.xml b/test/native/pom.xml
similarity index 63%
copy from spring/core/pom.xml
copy to test/native/pom.xml
index 1d5932069..459222a52 100644
--- a/spring/core/pom.xml
+++ b/test/native/pom.xml
@@ -20,37 +20,48 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.shardingsphere.elasticjob</groupId>
-        <artifactId>elasticjob-spring</artifactId>
+        <artifactId>elasticjob-test</artifactId>
         <version>3.1.0-SNAPSHOT</version>
     </parent>
-    <artifactId>elasticjob-spring-core</artifactId>
+    <artifactId>elasticjob-test-native</artifactId>
     <name>${project.artifactId}</name>
     
+    <properties>
+        <maven.deploy.skip>true</maven.deploy.skip>
+    </properties>
+    
     <dependencies>
         <dependency>
             <groupId>org.apache.shardingsphere.elasticjob</groupId>
             <artifactId>elasticjob-bootstrap</artifactId>
-            <version>${project.parent.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.zaxxer</groupId>
-                    <artifactId>HikariCP-java7</artifactId>
-                </exclusion>
-            </exclusions>
+            <version>${project.version}</version>
+            <scope>test</scope>
         </dependency>
         
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context-support</artifactId>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
         </dependency>
-        
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-test</artifactId>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
+    
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.graalvm.buildtools</groupId>
+                <artifactId>native-maven-plugin</artifactId>
+                <version>${native-maven-plugin.version}</version>
+            </plugin>
+        </plugins>
+    </build>
 </project>
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 000000000..1abcead7e
--- /dev/null
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.EnabledInNativeImage;
+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;
+
+@EnabledInNativeImage
+class JavaTest {
+    
+    private static TestingServer testingServer;
+    
+    private static CoordinatorRegistryCenter regCenter;
+    
+    private static TracingConfiguration<DataSource> tracingConfig;
+    
+    /**
+     * TODO Internally in {@link org.apache.curator.test.TestingServer},
+     *  {@code 
Files.createTempDirectory(DirectoryUtils.class.getSimpleName()).toFile())} 
calls {@link java.nio.file.Path#toFile()},
+     *  which is undesirable in both JAR and GraalVM Native Image,
+     *  see <a 
href="https://github.com/oracle/graal/issues/7804";>oracle/graal#7804</a>.
+     *  ElasticJob believe this requires changes on the apache/curator side.
+     *
+     * @throws Exception errors
+     */
+    @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 000000000..7fb818cd6
--- /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 000000000..7c87dffac
--- /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<Foo> {
+    
+    private final FooRepository fooRepository = 
FooRepositoryFactory.getFOO_REPOSITORY();
+    
+    @Override
+    public List<Foo> 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<Foo> 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 000000000..0932a700b
--- /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<Foo> 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 000000000..e6abaf1b1
--- /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<Long, Foo> 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<Foo> findTodoData(final String location, final int limit) {
+        List<Foo> result = new ArrayList<>(limit);
+        int count = 0;
+        for (Map.Entry<Long, Foo> 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 000000000..8ce70c48f
--- /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 000000000..a3f5b0027
--- /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 5c11d880a..4d6d5e326 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -30,5 +30,6 @@
     <modules>
         <module>e2e</module>
         <module>util</module>
+        <module>native</module>
     </modules>
 </project>

Reply via email to