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

jianglongtao 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 08031cd7b Add nativeTest for dynamically configuring jobs through 
Operation API in GraalVM Native Image (#2426)
08031cd7b is described below

commit 08031cd7b47e9cc3b067d2bcf98318335d8cafe5
Author: Ling Hengqian <linghengq...@outlook.com>
AuthorDate: Sun Aug 11 18:17:09 2024 +0800

    Add nativeTest for dynamically configuring jobs through Operation API in 
GraalVM Native Image (#2426)
---
 .../user-manual/usage/operation-api/_index.cn.md   |  22 +-
 .../user-manual/usage/operation-api/_index.en.md   |  22 +-
 .../reflect-config.json                            |   6 +
 .../reflect-config.json                            | 170 +++++++++++-
 .../resource-config.json                           |   3 +
 .../org.hamcrest/hamcrest/2.2/reflect-config.json  |  12 +
 test/native/pom.xml                                |   7 +-
 .../test/natived/commons/entity/Foo.java           |   2 +-
 .../commons/job/dataflow/JavaDataflowJob.java      |   2 +-
 .../job/dataflow/SpringBootDataflowJob.java        |   2 +-
 .../natived/commons/job/simple/JavaSimpleJob.java  |   2 +-
 .../commons/job/simple/SpringBootSimpleJob.java    |   2 +-
 .../natived/commons/repository/FooRepository.java  |   8 +-
 .../repository/SpringBootFooRepository.java        |  14 +-
 .../test/natived/it/operation/JavaTest.java        | 306 +++++++++++++++++++++
 .../test/natived/it/staticd/JavaTest.java          |   9 -
 test/native/src/test/resources/application.yml     |  10 +-
 17 files changed, 554 insertions(+), 45 deletions(-)

diff --git a/docs/content/user-manual/usage/operation-api/_index.cn.md 
b/docs/content/user-manual/usage/operation-api/_index.cn.md
index 4cae0e2d2..c74e94b3d 100644
--- a/docs/content/user-manual/usage/operation-api/_index.cn.md
+++ b/docs/content/user-manual/usage/operation-api/_index.cn.md
@@ -6,7 +6,15 @@ chapter = true
 
 ElasticJob 提供了 Java API,可以通过直接对注册中心进行操作的方式控制作业在分布式环境下的生命周期。
 
-该模块目前仍处于孵化状态。
+该模块目前仍处于孵化状态。可能的依赖配置如下,
+
+```xml
+<dependency>
+  <groupId>org.apache.shardingsphere.elasticjob</groupId>
+  <artifactId>elasticjob-lifecycle</artifactId>
+  <version>${elasticjob.version}</version>
+</dependency>
+```
 
 ## 配置类 API
 
@@ -43,11 +51,10 @@ ElasticJob 提供了 Java API,可以通过直接对注册中心进行操作的
 
 作业在不与当前运行中作业冲突的情况下才会触发执行,并在启动后自动清理此标记。
 
-方法签名:void trigger(Optional<String> jobName, Optional<String> serverIp)
+方法签名:void trigger(Optional<String> jobName)
 
 * **Parameters:**
   * jobName — 作业名称
-  * serverIp — 作业服务器IP地址
 
 ### 禁用作业
 
@@ -83,6 +90,15 @@ ElasticJob 提供了 Java API,可以通过直接对注册中心进行操作的
   * jobName — 作业名称
   * serverIp — 作业服务器IP地址
 
+### Dump 作业
+
+方法签名:String dump(String jobName, String instanceIp, int dumpPort)
+
+* **Parameters:**
+  * jobName — 作业名称
+  * serverIp — 作业服务器IP地址
+  * dumpPort — Dump port 
+
 ## 操作分片的 API
 
 类名称:`org.apache.shardingsphere.elasticjob.lifecycle.api.ShardingOperateAPI`
diff --git a/docs/content/user-manual/usage/operation-api/_index.en.md 
b/docs/content/user-manual/usage/operation-api/_index.en.md
index 846fe2137..3919ac9bb 100644
--- a/docs/content/user-manual/usage/operation-api/_index.en.md
+++ b/docs/content/user-manual/usage/operation-api/_index.en.md
@@ -6,7 +6,15 @@ chapter = true
 
 ElasticJob provides a Java API, which can control the life cycle of jobs in a 
distributed environment by directly operating the registry.
 
-The module is still in incubation.
+The module is still in incubation. Possible dependency configurations are as 
follows,
+
+```xml
+<dependency>
+  <groupId>org.apache.shardingsphere.elasticjob</groupId>
+  <artifactId>elasticjob-lifecycle</artifactId>
+  <version>${elasticjob.version}</version>
+</dependency>
+```
 
 ## Configuration API
 
@@ -43,11 +51,10 @@ Class 
name:`org.apache.shardingsphere.elasticjob.lifecycle.api.JobOperateAPI`
 
 The job will only trigger execution if it does not conflict with the currently 
running job, and this flag will be automatically cleared after it is started.
 
-Method signature:void trigger(Optional<String> jobName, Optional<String> 
serverIp)
+Method signature:void trigger(Optional<String> jobName)
 
 * **Parameters:**
   * jobName — Job name
-  * serverIp — IP address of the job server
 
 ### Disable job
 
@@ -83,6 +90,15 @@ Method signature:void remove(Optional<String> jobName, 
Optional<String> server
   * jobName — Job name
   * serverIp — IP address of the job server
 
+### Dump job
+
+Method signature:String dump(String jobName, String instanceIp, int dumpPort)
+
+* **Parameters:**
+  * jobName — Job name
+  * serverIp — IP address of the job server
+  * dumpPort — Dump port
+
 ## Operate sharding API
 
 Class 
name:`org.apache.shardingsphere.elasticjob.lifecycle.api.ShardingOperateAPI`
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
index cb28c8e58..33aa26038 100644
--- 
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
@@ -3,5 +3,11 @@
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration"},
   
"name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration",
   "allPublicMethods":true
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.LiteJob"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.LiteJob",
+  "allDeclaredMethods": true,
+  "allDeclaredConstructors": true
 }
 ]
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
index 5dfc6c97c..5681355f1 100644
--- 
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
@@ -3,6 +3,10 @@
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"},
   "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
 },
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"},
+  "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
+},
 {
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"},
   "name":"[Ljava.sql.Statement;"
@@ -71,30 +75,51 @@
 {
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
   
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
-  "methods":[{"name":"setProps","parameterTypes":["java.util.Properties"] }]
+  "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, 
{"name":"setProps","parameterTypes":["java.util.Properties"] }]
 },
 {
-  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.facade.JobFacade"},
   
"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" [...]
+  "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
 },
 {
   
"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":[ [...]
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"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":"getJob [...]
 },
 {
   
"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.failover.FailoverListenerManager$FailoverSettingsChangedJobListener"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setCron","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":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, 
{"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMoni [...]
+},
 {
   
"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.sharding.ExecutionContextService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ExecutionService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.MonitorExecutionListenerManager$MonitorExecutionSettingsChangedJobListener"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setCron","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":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, 
{"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMoni [...]
+},
 {
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ListenServersChangedJobListener"},
   
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
@@ -103,7 +128,25 @@
 {
   
"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"] }]
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setCron","parameterTypes":["java.lang.String"] }, 
{"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"] [...]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.settings.JobConfigurationAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"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":"getJob [...]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.JobStatisticsAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setCron","parameterTypes":["java.lang.String"] }, 
{"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"] [...]
 },
 {
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
@@ -150,6 +193,42 @@
   "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",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.operate.JobOperateAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.JobStatisticsAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.ServerStatisticsAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.ShardingStatisticsAPIImpl"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+  "allDeclaredFields":true,
+  "methods":[{"name":"<init>","parameterTypes":[] }, 
{"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, 
{"name":"setServerIp","parameterTypes":["java.lang.String"] }]
+},
 {
   
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
   
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
@@ -164,7 +243,52 @@
   
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstanceCustomizer"
 },
 {
-  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.AverageAllocationJobShardingStrategy",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.OdevitySortByNameJobShardingStrategy",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+  
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.RoundRobinByNameJobShardingStrategy",
+  "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"},
+  
"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.failover.FailoverListenerManager$FailoverSettingsChangedJobListener"},
+  
"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.sharding.MonitorExecutionListenerManager$MonitorExecutionSettingsChangedJobListener"},
+  
"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.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+  
"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.lifecycle.internal.settings.JobConfigurationAPIImpl"},
+  
"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.lifecycle.internal.statistics.JobStatisticsAPIImpl"},
   
"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"] }]
@@ -232,7 +356,37 @@
   
"name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.SQLServerTracingStorageDatabaseType"
 },
 {
-  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"},
+  
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"},
+  
"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.failover.FailoverListenerManager$FailoverSettingsChangedJobListener"},
+  
"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.sharding.MonitorExecutionListenerManager$MonitorExecutionSettingsChangedJobListener"},
+  
"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.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+  
"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.lifecycle.internal.settings.JobConfigurationAPIImpl"},
+  
"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.lifecycle.internal.statistics.JobStatisticsAPIImpl"},
   
"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"] }]
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
index 07292ac06..7fe241755 100644
--- 
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
@@ -9,6 +9,9 @@
   }, {
     
"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.kernel.internal.sharding.ShardingService"},
+    
"pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.JobShardingStrategy\\E"
   }, {
     
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.exception.RegExceptionHandler"},
     
"pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.reg.exception.IgnoredExceptionProvider\\E"
diff --git 
a/reachability-metadata/src/main/resources/META-INF/native-image/org.hamcrest/hamcrest/2.2/reflect-config.json
 
b/reachability-metadata/src/main/resources/META-INF/native-image/org.hamcrest/hamcrest/2.2/reflect-config.json
new file mode 100644
index 000000000..0f9e3726d
--- /dev/null
+++ 
b/reachability-metadata/src/main/resources/META-INF/native-image/org.hamcrest/hamcrest/2.2/reflect-config.json
@@ -0,0 +1,12 @@
+[
+{
+  "condition":{"typeReachable":"org.hamcrest.internal.ReflectiveTypeFinder"},
+  "name":"org.hamcrest.core.StringStartsWith",
+  "queryAllDeclaredMethods":true
+},
+{
+  "condition":{"typeReachable":"org.hamcrest.internal.ReflectiveTypeFinder"},
+  "name":"org.hamcrest.core.SubstringMatcher",
+  "queryAllDeclaredMethods":true
+}
+]
diff --git a/test/native/pom.xml b/test/native/pom.xml
index 00cca3bdd..1370b8b48 100644
--- a/test/native/pom.xml
+++ b/test/native/pom.xml
@@ -40,7 +40,12 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-        
+        <dependency>
+            <groupId>org.apache.shardingsphere.elasticjob</groupId>
+            <artifactId>elasticjob-lifecycle</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.awaitility</groupId>
             <artifactId>awaitility</artifactId>
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
index 7fb818cd6..b498f1e15 100644
--- 
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
@@ -39,7 +39,7 @@ public final class Foo implements Serializable {
     private Status status;
     
     public enum Status {
-        TODO,
+        UNFINISHED,
         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
index 7c87dffac..1b3a69431 100644
--- 
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
@@ -39,7 +39,7 @@ public class JavaDataflowJob implements DataflowJob<Foo> {
                 new SimpleDateFormat("HH:mm:ss").format(new Date()),
                 Thread.currentThread().getId(),
                 "DATAFLOW FETCH");
-        return 
fooRepository.findTodoData(shardingContext.getShardingParameter(), 10);
+        return 
fooRepository.findUnfinishedData(shardingContext.getShardingParameter(), 10);
     }
     
     @Override
diff --git 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java
 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java
index 992ca14dc..1f77bba89 100644
--- 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java
@@ -47,7 +47,7 @@ public class SpringBootDataflowJob implements 
DataflowJob<Foo> {
                 new SimpleDateFormat("HH:mm:ss").format(new Date()),
                 Thread.currentThread().getId(),
                 "DATAFLOW FETCH");
-        return 
springBootFooRepository.findTodoData(shardingContext.getShardingParameter(), 
10);
+        return 
springBootFooRepository.findUnfinishedData(shardingContext.getShardingParameter(),
 10);
     }
     
     @Override
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
index 0932a700b..58978416c 100644
--- 
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
@@ -39,7 +39,7 @@ public class JavaSimpleJob implements SimpleJob {
                 new SimpleDateFormat("HH:mm:ss").format(new Date()),
                 Thread.currentThread().getId(),
                 "SIMPLE");
-        List<Foo> data = 
fooRepository.findTodoData(shardingContext.getShardingParameter(), 10);
+        List<Foo> data = 
fooRepository.findUnfinishedData(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/job/simple/SpringBootSimpleJob.java
 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java
index 1185636d2..e76f53f92 100644
--- 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java
@@ -45,7 +45,7 @@ public class SpringBootSimpleJob implements SimpleJob {
                 new SimpleDateFormat("HH:mm:ss").format(new Date()),
                 Thread.currentThread().getId(),
                 "SIMPLE");
-        
springBootFooRepository.findTodoData(shardingContext.getShardingParameter(), 10)
+        
springBootFooRepository.findUnfinishedData(shardingContext.getShardingParameter(),
 10)
                 .forEach(each -> 
springBootFooRepository.setCompleted(each.getId()));
     }
 }
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
index e6abaf1b1..f0ea27a58 100644
--- 
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
@@ -37,21 +37,21 @@ public class FooRepository {
     
     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)));
+                .forEachOrdered(i -> data.put(i, new Foo(i, location, 
Foo.Status.UNFINISHED)));
     }
     
     /**
-     * Find todoData.
+     * Find Unfinished Data.
      * @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) {
+    public List<Foo> findUnfinishedData(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) {
+            if (foo.getLocation().equals(location) && foo.getStatus() == 
Foo.Status.UNFINISHED) {
                 result.add(foo);
                 count++;
                 if (count == limit) {
diff --git 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
index cafe2bb02..b9587171f 100644
--- 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
@@ -32,28 +32,28 @@ public class SpringBootFooRepository {
     private final Map<Long, Foo> data = new ConcurrentHashMap<>(300, 1);
     
     public SpringBootFooRepository() {
-        addData(0L, 100L, "Beijing");
-        addData(100L, 200L, "Shanghai");
-        addData(200L, 300L, "Guangzhou");
+        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)));
+                .forEachOrdered(i -> data.put(i, new Foo(i, location, 
Foo.Status.UNFINISHED)));
     }
     
     /**
-     * Find todoData.
+     * Find Unfinished Data.
      * @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) {
+    public List<Foo> findUnfinishedData(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) {
+            if (foo.getLocation().equals(location) && foo.getStatus() == 
Foo.Status.UNFINISHED) {
                 result.add(foo);
                 count++;
                 if (count == limit) {
diff --git 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/operation/JavaTest.java
 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/operation/JavaTest.java
new file mode 100644
index 000000000..72305f2af
--- /dev/null
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/operation/JavaTest.java
@@ -0,0 +1,306 @@
+/*
+ * 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.it.operation;
+
+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.ScheduleJobBootstrap;
+import 
org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO;
+import 
org.apache.shardingsphere.elasticjob.kernel.tracing.config.TracingConfiguration;
+import org.apache.shardingsphere.elasticjob.lifecycle.api.JobConfigurationAPI;
+import org.apache.shardingsphere.elasticjob.lifecycle.api.JobOperateAPI;
+import org.apache.shardingsphere.elasticjob.lifecycle.api.JobStatisticsAPI;
+import org.apache.shardingsphere.elasticjob.lifecycle.api.ServerStatisticsAPI;
+import org.apache.shardingsphere.elasticjob.lifecycle.api.ShardingOperateAPI;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.api.ShardingStatisticsAPI;
+import org.apache.shardingsphere.elasticjob.lifecycle.domain.JobBriefInfo;
+import org.apache.shardingsphere.elasticjob.lifecycle.domain.ServerBriefInfo;
+import org.apache.shardingsphere.elasticjob.lifecycle.domain.ShardingInfo;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.operate.JobOperateAPIImpl;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.operate.ShardingOperateAPIImpl;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.settings.JobConfigurationAPIImpl;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.JobStatisticsAPIImpl;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.ServerStatisticsAPIImpl;
+import 
org.apache.shardingsphere.elasticjob.lifecycle.internal.statistics.ShardingStatisticsAPIImpl;
+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.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.function.Executable;
+
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+@EnabledInNativeImage
+class JavaTest {
+    
+    private static TestingServer testingServer;
+    
+    private static CoordinatorRegistryCenter firstRegCenter;
+    
+    private static CoordinatorRegistryCenter secondRegCenter;
+    
+    private static TracingConfiguration<DataSource> 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)).ignoreExceptions().until(client::isConnected);
+        }
+        firstRegCenter = new ZookeeperRegistryCenter(new 
ZookeeperConfiguration(testingServer.getConnectString(), 
"elasticjob-test-native-java"));
+        firstRegCenter.init();
+        secondRegCenter = new ZookeeperRegistryCenter(new 
ZookeeperConfiguration(testingServer.getConnectString(), 
"elasticjob-test-native-java"));
+        secondRegCenter.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 {
+        firstRegCenter.close();
+        secondRegCenter.close();
+        testingServer.close();
+    }
+    
+    /**
+     * TODO Executing {@link 
JobConfigurationAPI#removeJobConfiguration(String)} will always cause the 
listener
+     *  to throw an exception similar to {@code Caused by: 
java.lang.IllegalStateException: Expected state [STARTED] was [STOPPED]} .
+     *  This is not acceptable behavior.
+     */
+    @Test
+    void testJobConfigurationAPI() {
+        String jobName = "testJobConfigurationAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        JobConfigurationAPI jobConfigAPI = new 
JobConfigurationAPIImpl(secondRegCenter);
+        JobConfigurationPOJO jobConfig = 
jobConfigAPI.getJobConfiguration(jobName);
+        assertThat(jobConfig, notNullValue());
+        assertThat(jobConfig.getJobName(), is(jobName));
+        assertThat(jobConfig.getCron(), is("0/5 * * * * ?"));
+        assertThat(jobConfig.getShardingItemParameters(), 
is("0=Norddorf,1=Bordeaux,2=Somerset"));
+        JobConfigurationPOJO newJobConfig = new JobConfigurationPOJO();
+        newJobConfig.setJobName(jobConfig.getJobName());
+        newJobConfig.setShardingTotalCount(jobConfig.getShardingTotalCount());
+        newJobConfig.setCron("0/10 * * * * ?");
+        
newJobConfig.setShardingItemParameters(jobConfig.getShardingItemParameters());
+        
newJobConfig.setJobExtraConfigurations(jobConfig.getJobExtraConfigurations());
+        jobConfigAPI.updateJobConfiguration(newJobConfig);
+        JobConfigurationPOJO newTestJavaSimpleJob = 
jobConfigAPI.getJobConfiguration(jobName);
+        assertThat(newTestJavaSimpleJob, notNullValue());
+        assertThat(newTestJavaSimpleJob.getCron(), is("0/10 * * * * ?"));
+        jobConfigAPI.removeJobConfiguration(jobName);
+        assertThat(jobConfigAPI.getJobConfiguration(jobName), nullValue());
+        job.shutdown();
+    }
+    
+    /**
+     * TODO The most embarrassing thing is that there seems to be no simple 
logic to
+     *  test {@link JobOperateAPI#trigger(String)} and {@link 
JobOperateAPI#dump(String, String, int)}.
+     */
+    @Test
+    void testJobOperateAPI() {
+        String jobName = "testJobOperateAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        List<ServerBriefInfo> serverBriefInfos = new ArrayList<>(new 
ServerStatisticsAPIImpl(secondRegCenter).getAllServersBriefInfo());
+        assertThat(serverBriefInfos.size(), is(1));
+        String serverIp = serverBriefInfos.get(0).getServerIp();
+        JobOperateAPI jobOperateAPI = new JobOperateAPIImpl(secondRegCenter);
+        jobOperateAPI.disable(jobName, serverIp);
+        JobStatisticsAPIImpl jobStatisticsAPI = new 
JobStatisticsAPIImpl(secondRegCenter);
+        JobBriefInfo firstJobBriefInfo = 
jobStatisticsAPI.getJobBriefInfo(jobName);
+        assertThat(firstJobBriefInfo, notNullValue());
+        assertThat(firstJobBriefInfo.getStatus(), 
is(JobBriefInfo.JobStatus.DISABLED));
+        jobOperateAPI.enable(jobName, serverIp);
+        JobBriefInfo secondJobBriefInfo = 
jobStatisticsAPI.getJobBriefInfo(jobName);
+        assertThat(secondJobBriefInfo, notNullValue());
+        assertThat(secondJobBriefInfo.getStatus(), 
is(JobBriefInfo.JobStatus.SHARDING_FLAG));
+        jobOperateAPI.remove(jobName, serverIp);
+        JobBriefInfo thirdJobBriefInfo = 
jobStatisticsAPI.getJobBriefInfo(jobName);
+        assertThat(thirdJobBriefInfo, notNullValue());
+        assertThat(thirdJobBriefInfo.getStatus(), 
is(JobBriefInfo.JobStatus.CRASHED));
+        job.shutdown();
+    }
+    
+    @Test
+    void testShardingOperateAPI() {
+        String jobName = "testShardingOperateAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        ShardingOperateAPI shardingOperateAPI = new 
ShardingOperateAPIImpl(secondRegCenter);
+        shardingOperateAPI.disable(jobName, "0");
+        ShardingStatisticsAPI shardingStatisticsAPI = new 
ShardingStatisticsAPIImpl(secondRegCenter);
+        List<ShardingInfo> firstShardingInfos = 
shardingStatisticsAPI.getShardingInfo(jobName)
+                .stream()
+                .filter(shardingInfo -> 0 == shardingInfo.getItem())
+                .collect(Collectors.toList());
+        assertThat(firstShardingInfos.size(), is(1));
+        assertThat(firstShardingInfos.get(0).getStatus(), 
is(ShardingInfo.ShardingStatus.DISABLED));
+        shardingOperateAPI.enable(jobName, "0");
+        List<ShardingInfo> secondShardingInfos = 
shardingStatisticsAPI.getShardingInfo(jobName)
+                .stream()
+                .filter(shardingInfo -> 0 == shardingInfo.getItem())
+                .collect(Collectors.toList());
+        assertThat(secondShardingInfos.size(), is(1));
+        assertThat(secondShardingInfos.get(0).getStatus(), 
is(ShardingInfo.ShardingStatus.SHARDING_FLAG));
+        job.shutdown();
+    }
+    
+    @Test
+    void testJobStatisticsAPI() {
+        String jobName = "testJobStatisticsAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        JobStatisticsAPI jobStatisticsAPI = new 
JobStatisticsAPIImpl(secondRegCenter);
+        assertThat(jobStatisticsAPI.getJobsTotalCount(), is(1));
+        JobBriefInfo jobBriefInfo = jobStatisticsAPI.getJobBriefInfo(jobName);
+        assertThat(jobBriefInfo, notNullValue());
+        assertThat(jobBriefInfo.getJobName(), is(jobName));
+        assertThat(jobBriefInfo.getStatus(), 
is(JobBriefInfo.JobStatus.SHARDING_FLAG));
+        assertThat(jobBriefInfo.getDescription(), is(""));
+        assertThat(jobBriefInfo.getCron(), is("0/5 * * * * ?"));
+        assertThat(jobBriefInfo.getInstanceCount(), is(1));
+        assertThat(jobBriefInfo.getShardingTotalCount(), is(3));
+        assertThat(jobStatisticsAPI.getAllJobsBriefInfo().size(), is(1));
+        assertDoesNotThrow(() -> {
+            List<String> ipList = secondRegCenter.getChildrenKeys("/" + 
jobName + "/servers");
+            assertThat(ipList.size(), is(1));
+            
assertThat(jobStatisticsAPI.getJobsBriefInfo(ipList.get(0)).size(), is(1));
+        });
+        job.shutdown();
+    }
+    
+    /**
+     * TODO The logic inside {@link 
org.junit.jupiter.api.Assertions#assertDoesNotThrow(Executable)} should be 
removed.
+     */
+    @Test
+    void testServerStatisticsAPI() {
+        String jobName = "testServerStatisticsAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        ServerStatisticsAPI serverStatisticsAPI = new 
ServerStatisticsAPIImpl(secondRegCenter);
+        assertThat(serverStatisticsAPI.getServersTotalCount(), is(1));
+        Collection<ServerBriefInfo> allServersBriefInfo = 
serverStatisticsAPI.getAllServersBriefInfo();
+        assertThat(allServersBriefInfo.size(), is(1));
+        allServersBriefInfo.stream().findFirst().ifPresent(serverBriefInfo -> {
+            String serverIp = serverBriefInfo.getServerIp();
+            assertThat(serverIp, notNullValue());
+            Set<String> instances = serverBriefInfo.getInstances();
+            assertThat(instances.size(), is(1));
+            assertThat(instances.stream().findFirst().isPresent(), is(true));
+            assertThat(instances.stream().findFirst().get(), 
startsWith(serverIp + "@-@"));
+            Set<String> jobNames = serverBriefInfo.getJobNames();
+            assertThat(jobNames.size(), is(1));
+            assertThat(jobNames.stream().findFirst().isPresent(), is(true));
+            assertThat(jobNames.stream().findFirst().get(), is(jobName));
+            assertThat(serverBriefInfo.getInstancesNum(), is(1));
+            assertThat(serverBriefInfo.getJobsNum(), is(1));
+            assertThat(serverBriefInfo.getDisabledJobsNum().intValue(), is(0));
+        });
+        job.shutdown();
+        assertDoesNotThrow(() -> {
+            JobConfigurationAPI jobConfigAPI = new 
JobConfigurationAPIImpl(secondRegCenter);
+            jobConfigAPI.removeJobConfiguration(jobName);
+        });
+    }
+    
+    @Test
+    void testShardingStatisticsAPI() {
+        String jobName = "testShardingStatisticsAPI";
+        ScheduleJobBootstrap job = new ScheduleJobBootstrap(firstRegCenter, 
new JavaSimpleJob(),
+                JobConfiguration.newBuilder(jobName, 3)
+                        .cron("0/5 * * * * ?")
+                        
.shardingItemParameters("0=Norddorf,1=Bordeaux,2=Somerset")
+                        .addExtraConfigurations(tracingConfig)
+                        .build());
+        job.schedule();
+        ShardingStatisticsAPI shardingStatisticsAPI = new 
ShardingStatisticsAPIImpl(secondRegCenter);
+        Awaitility.await()
+                .atMost(1L, TimeUnit.MINUTES)
+                .ignoreExceptions()
+                .until(() -> 3 == 
shardingStatisticsAPI.getShardingInfo(jobName).size());
+        shardingStatisticsAPI.getShardingInfo(jobName).forEach(shardingInfo -> 
{
+            String serverIp = shardingInfo.getServerIp();
+            assertThat(serverIp, notNullValue());
+            assertThat(shardingInfo.getInstanceId(), startsWith(serverIp + 
"@-@"));
+            ShardingInfo.ShardingStatus status = shardingInfo.getStatus();
+            assertThat(status, not(ShardingInfo.ShardingStatus.SHARDING_FLAG));
+            assertThat(status, not(ShardingInfo.ShardingStatus.DISABLED));
+            assertThat(shardingInfo.isFailover(), is(false));
+        });
+        job.shutdown();
+    }
+}
diff --git 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/staticd/JavaTest.java
 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/staticd/JavaTest.java
index bb4e91163..1e35c2923 100644
--- 
a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/staticd/JavaTest.java
+++ 
b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/it/staticd/JavaTest.java
@@ -58,15 +58,6 @@ class JavaTest {
     
     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();
diff --git a/test/native/src/test/resources/application.yml 
b/test/native/src/test/resources/application.yml
index 60e962615..f1c82ddfa 100644
--- a/test/native/src/test/resources/application.yml
+++ b/test/native/src/test/resources/application.yml
@@ -15,8 +15,8 @@
 # limitations under the License.
 #
 
-# `elasticjob.regCenter.serverLists` is dynamically defined in 
`org.apache.shardingsphere.elasticjob.test.natived.SpirngBootTest`
-# `elasticjob.dump.port` is dynamically defined in 
`org.apache.shardingsphere.elasticjob.test.natived.SpirngBootTest`
+# `elasticjob.regCenter.serverLists` is dynamically defined in 
`org.springframework.test.context.DynamicPropertySource`
+# `elasticjob.dump.port` is dynamically defined in 
`org.springframework.test.context.DynamicPropertySource`
 elasticjob:
   tracing:
     type: RDB
@@ -26,18 +26,18 @@ elasticjob:
       username: sa
       password:
   regCenter:
-    namespace: elasticjob-springboot
+    namespace: elasticjob-test-native-springboot
   jobs:
     simpleJob:
       elasticJobClass: 
org.apache.shardingsphere.elasticjob.test.natived.commons.job.simple.SpringBootSimpleJob
       cron: 0/5 * * * * ?
       shardingTotalCount: 3
-      shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou
+      shardingItemParameters: 0=Norddorf,1=Bordeaux,2=Somerset
     dataflowJob:
       elasticJobClass: 
org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow.SpringBootDataflowJob
       cron: 0/5 * * * * ?
       shardingTotalCount: 3
-      shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou
+      shardingItemParameters: 0=Norddorf,1=Bordeaux,2=Somerset
     scriptJob:
       elasticJobType: SCRIPT
       cron: 0/10 * * * * ?

Reply via email to