diff --git a/.github/workflows/graalvm.yml b/.github/workflows/graalvm.yml
index fcff1f14e3..1216b9307f 100644
--- a/.github/workflows/graalvm.yml
+++ b/.github/workflows/graalvm.yml
@@ -34,7 +34,7 @@ jobs:
os: [ 'ubuntu-latest' ]
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up GraalVM CE ${{ matrix.java }}
uses: graalvm/setup-graalvm@v1
with:
@@ -42,6 +42,7 @@ jobs:
distribution: 'graalvm-community'
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'maven'
+ native-image-job-reports: 'true'
- 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/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java b/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java
index dc0599ccdd..31cfe784d1 100644
--- a/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java
+++ b/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java
@@ -30,7 +30,7 @@
/**
* One off job bootstrap.
*/
-public final class OneOffJobBootstrap implements JobBootstrap {
+public class OneOffJobBootstrap implements JobBootstrap {
private final JobScheduler jobScheduler;
diff --git a/docs/content/user-manual/configuration/graalvm-native-image.cn.md b/docs/content/user-manual/configuration/graalvm-native-image.cn.md
index 8a892fa376..3744146324 100644
--- a/docs/content/user-manual/configuration/graalvm-native-image.cn.md
+++ b/docs/content/user-manual/configuration/graalvm-native-image.cn.md
@@ -104,10 +104,29 @@ graalvmNative {
若 `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`。
+长话短说,用户应该避免在作业内包含类似如下的逻辑,
+
+```java
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermissions;
+
+public class ExampleUtils {
+ public void setPosixFilePermissions() throws IOException {
+ URL resource = ExampleUtils.class.getResource("/script/demo.sh");
+ assert resource != null;
+ Path path = Paths.get(resource.getPath());
+ Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-xr-x"));
+ }
+}
+```
-3. ElasticJob 的 Spring 命名空间集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` 尚未在 GraalVM Native Image 下可用。
+3. `企业微信通知策略`,`钉钉通知策略`,`邮件通知策略`尚未在 GraalVM Native Image 下可用。
-4. ElasticJob 的 Spring Boot Starter 集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-boot-starter` 尚未在 GraalVM Native Image 下可用。
+4. ElasticJob 的 Spring 命名空间集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` 尚未在 GraalVM Native Image 下可用。
## 贡献 GraalVM Reachability Metadata
diff --git a/docs/content/user-manual/configuration/graalvm-native-image.en.md b/docs/content/user-manual/configuration/graalvm-native-image.en.md
index 5b9018c8c5..028f20afc9 100644
--- a/docs/content/user-manual/configuration/graalvm-native-image.en.md
+++ b/docs/content/user-manual/configuration/graalvm-native-image.en.md
@@ -106,10 +106,29 @@ Users can quickly collect GraalVM Reachability Metadata through the GraalVM Trac
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`.
+Long story short, users should avoid including logic like the following in their jobs,
+
+```java
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermissions;
+
+public class ExampleUtils {
+ public void setPosixFilePermissions() throws IOException {
+ URL resource = ExampleUtils.class.getResource("/script/demo.sh");
+ assert resource != null;
+ Path path = Paths.get(resource.getPath());
+ Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-xr-x"));
+ }
+}
+```
-3. The Spring namespace integration module `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` of ElasticJob is not yet available under GraalVM Native Image.
+3. `WeCom Notification Policy`, `DingTalk Notification Policy`, and `Email Notification Policy` are not yet available in 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.
+4. The Spring namespace integration module `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` of ElasticJob is not yet available under GraalVM Native Image.
## Contribute GraalVM Reachability Metadata
diff --git a/pom.xml b/pom.xml
index 15a3aa9ca4..db8ce221dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,6 +93,9 @@
2.2.224
4.0.3
+
+ 3.2.8
+
3.2.1
3.11.0
@@ -1015,6 +1018,19 @@
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot-dependencies.version}
+
+
+ process-test-aot
+
+ process-test-aot
+
+
+
+
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
index fd2d4325f4..25cf820544 100644
--- 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
@@ -1,6 +1,6 @@
[
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"},
"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
index b934e85204..49e892502b 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
@@ -4,9 +4,12 @@
"name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
- "name":"java.util.Properties",
- "methods":[{"name":"","parameterTypes":[] }]
+ "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;"
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
@@ -23,6 +26,11 @@
"name":"java.util.Properties",
"methods":[{"name":"","parameterTypes":[] }]
},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ListenServersChangedJobListener"},
+ "name":"java.util.Properties",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
"name":"java.util.Properties",
@@ -48,7 +56,7 @@
"methods":[{"name":"","parameterTypes":[] }]
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"name":"org.apache.shardingsphere.elasticjob.http.executor.HttpJobExecutor"
},
{
@@ -59,16 +67,10 @@
"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"] }]
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
@@ -76,16 +78,15 @@
"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":"","parameterTypes":[] }, {"name":"setDescription","parameterTypes":["java.lang.String"] }, {"name":"setDisabled","parameterTypes":["boolean"] }, {"name":"setFailover","parameterTypes":["boolean"] }, {"name":"setJobExtraConfigurations","parameterTypes":["java.util.Collection"] }, {"name":"setJobName","parameterTypes":["java.lang.String"] }, {"name":"setJobParameter","parameterTypes":["java.lang.String"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }]
+ "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":[] }, {"name":"getLabel","parameterTypes":[] }, {"name":"getMaxTimeDiffSeconds","parameterTypes":[] }, {"name":"getProps","parameterTypes":[] }, {"name":"getReconcileIntervalMinutes","parameterTypes":[] }, {"name":"getShardingItemParameters","parameterTypes":[] }, {"name":"getShardingTotalCount","parameterTypes":[] }, {"name":"getTimeZone","parameterTypes":[] }, {"name":"isDisabled","parameterTypes":[] }, {"name":"isFailover","parameterTypes":[] }, {"name":"isMisfire","parameterTypes":[] }, {"name":"isMonitorExecution","parameterTypes":[] }, {"name":"isOverwrite","parameterTypes":[] }, {"name":"isStaticSharding","parameterTypes":[] }]
+ "methods":[{"name":"","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":"getJobShardingStrategyType","parameterTypes":[] }, {"name":"getLabel","parameterTypes":[] }, {"name":"getMaxTimeDiffSeconds","parameterTypes":[] }, {"name":"getProps","parameterTypes":[] }, {"name":"getReconcileIntervalMinutes","parameterTypes":[] }, {"name":"getShardingItemParameters","parameterTypes":[] }, {"name":"getShardingTotalCount","parameterTypes":[] }, {"name":"getTimeZone","parameterTypes":[] }, {"name":"isDisabled","parameterTypes":[] }, {"name":"isFailover","parameterTypes":[] }, {"name":"isMisfire","parameterTypes":[] }, {"name":"isMonitorExecution","parameterTypes":[] }, {"name":"isOverwrite","parameterTypes":[] }, {"name":"isStaticSharding","parameterTypes":[] }, {"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"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }]
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.failover.FailoverListenerManager"},
@@ -98,15 +99,36 @@
"methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }]
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ExecutionContextService"},
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
- "queryAllPublicMethods":true
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+ "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.ShardingListenerManager$ListenServersChangedJobListener"},
"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.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","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"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO",
+ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
+ "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.JobConfigurationPOJOBeanInfo"
@@ -115,22 +137,20 @@
"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
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin"
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin",
- "queryAllPublicMethods":true,
"methods":[{"name":"","parameterTypes":[] }, {"name":"setCleanShutdown","parameterTypes":["boolean"] }]
},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
+ "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.JobShutdownHookPluginBeanInfo"
@@ -139,15 +159,9 @@
"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
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance"
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceNode"},
@@ -157,16 +171,20 @@
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceService"},
- "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance"
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, {"name":"setServerIp","parameterTypes":["java.lang.String"] }]
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
"name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
- "queryAllPublicMethods":true
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, {"name":"setServerIp","parameterTypes":["java.lang.String"] }]
},
{
- "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.spring.boot.job.ElasticJobBootstrapConfiguration"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance",
+ "queryAllPublicMethods":true
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
@@ -177,7 +195,28 @@
"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":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.OdevitySortByNameJobShardingStrategy",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.RoundRobinByNameJobShardingStrategy",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"},
+ "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration",
+ "allDeclaredFields":true,
+ "methods":[{"name":"","parameterTypes":[] }, {"name":"setTracingStorageConfiguration","parameterTypes":["org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingStorageConfiguration"] }, {"name":"setType","parameterTypes":["java.lang.String"] }]
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"},
"name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration",
"allDeclaredFields":true,
"methods":[{"name":"","parameterTypes":[] }, {"name":"setTracingStorageConfiguration","parameterTypes":["org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingStorageConfiguration"] }, {"name":"setType","parameterTypes":["java.lang.String"] }]
@@ -191,7 +230,7 @@
"name":"org.apache.shardingsphere.elasticjob.reg.zookeeper.exception.ZookeeperCuratorIgnoredExceptionProvider"
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"name":"org.apache.shardingsphere.elasticjob.script.executor.ScriptJobExecutor"
},
{
@@ -199,17 +238,21 @@
"name":"org.apache.shardingsphere.elasticjob.simple.executor.SimpleJobExecutor"
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"name":"org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListener",
"queryAllDeclaredMethods":true
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProviderFactory"},
+ "name":"org.apache.shardingsphere.elasticjob.spring.core.setup.SpringProxyJobClassNameProvider"
+},
+{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListener",
"queryAllDeclaredMethods":true
},
{
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListenerFactory"
},
{
@@ -241,7 +284,13 @@
"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":"","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":"","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 101e57e2fc..7fe2417552 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
@@ -1,25 +1,31 @@
{
"resources":{
"includes":[{
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"},
+ "pattern":"\\QMETA-INF/services/java.sql.Driver\\E"
+ }, {
"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.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"
}, {
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"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"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.item.type.TypedJobItemExecutor\\E"
}, {
- "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListenerFactory\\E"
}, {
"condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.storage.TracingStorageConverterFactory"},
@@ -34,7 +40,10 @@
"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"},
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"},
+ "pattern":"\\Qorg/h2/util/data.zip\\E"
+ }, {
+ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"},
"pattern":"\\Qorg/quartz/core/quartz-build.properties\\E"
}]},
"bundles":[]
diff --git a/spring/boot-starter/pom.xml b/spring/boot-starter/pom.xml
index 7fa77d5704..f685104a77 100644
--- a/spring/boot-starter/pom.xml
+++ b/spring/boot-starter/pom.xml
@@ -42,6 +42,7 @@
org.springframework.boot
spring-boot-starter
+ true
org.springframework.boot
diff --git a/test/native/native-image-filter/extra-filter.json b/test/native/native-image-filter/extra-filter.json
index 9e706a39d4..fdf91f4da0 100644
--- a/test/native/native-image-filter/extra-filter.json
+++ b/test/native/native-image-filter/extra-filter.json
@@ -2,13 +2,12 @@
"rules": [
{"includeClasses": "**"},
- {"excludeClasses": "com.google.common.util.concurrent.**"},
- {"excludeClasses": "com.zaxxer.hikari.**"},
+ {"excludeClasses": "com.**"},
{"excludeClasses": "java.**"},
{"includeClasses": "java.util.Properties"},
- {"excludeClasses": "org.apache.zookeeper.**"},
- {"excludeClasses": "org.quartz.**"},
- {"excludeClasses": "sun.misc.**"},
+ {"excludeClasses": "org.**"},
+ {"includeClasses": "org.apache.shardingsphere.elasticjob.**"},
+ {"excludeClasses": "sun.**"},
{"excludeClasses": "org.apache.shardingsphere.elasticjob.test.natived.**"}
],
diff --git a/test/native/pom.xml b/test/native/pom.xml
index 459222a528..f3cca8f28e 100644
--- a/test/native/pom.xml
+++ b/test/native/pom.xml
@@ -28,12 +28,14 @@
true
+ 2.0.7
+ 1.4.14
org.apache.shardingsphere.elasticjob
- elasticjob-bootstrap
+ elasticjob-spring-boot-starter
${project.version}
test
@@ -53,6 +55,24 @@
curator-test
test
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+ ${spring-boot-dependencies.version}
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot-dependencies.version}
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring-boot-dependencies.version}
+ test
+
@@ -62,6 +82,11 @@
native-maven-plugin
${native-maven-plugin.version}
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot-dependencies.version}
+
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.java
new file mode 100644
index 0000000000..e62b3d87b5
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ElasticJobSpringBootStarterApplication {
+
+ // CHECKSTYLE:OFF
+ public static void main(final String[] args) {
+ // CHECKSTYLE:ON
+ SpringApplication.run(ElasticJobSpringBootStarterApplication.class, args);
+ }
+}
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
index 1abcead7ef..8b8212854c 100644
--- 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
@@ -157,7 +157,7 @@ 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())
+ .setProperty(ScriptJobProperties.SCRIPT_KEY, Paths.get("src/test/resources/test-native/sh/demo.sh").toString())
.addExtraConfigurations(tracingConfig)
.build());
assertDoesNotThrow(() -> {
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java
new file mode 100644
index 0000000000..73e6d9752d
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.curator.CuratorZookeeperClient;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.apache.curator.test.TestingServer;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledInNativeImage;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+@SpringBootTest(
+ classes = ElasticJobSpringBootStarterApplication.class,
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestPropertySource(locations = "classpath:application.yml")
+@EnabledInNativeImage
+public class SpirngBootTest {
+
+ private static TestingServer testingServer;
+
+ private MockMvc mockMvc;
+
+ @BeforeAll
+ static void beforeAll() throws Exception {
+ testingServer = new TestingServer(6181);
+ 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);
+ }
+ }
+
+ @AfterAll
+ static void afterAll() throws IOException {
+ testingServer.close();
+ }
+
+ @BeforeEach
+ void setup(final WebApplicationContext webApplicationContext) {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
+ .defaultResponseCharacterEncoding(StandardCharsets.UTF_8)
+ .build();
+ }
+
+ @DynamicPropertySource
+ static void elasticjobProperties(final DynamicPropertyRegistry registry) {
+ registry.add("elasticjob.regCenter.serverLists", () -> testingServer.getConnectString());
+ }
+
+ /**
+ * ElasticJob Spring Boot Starter requires that all Spring Boot Applications be shut down before shutting down Zookeeper Server.
+ * That's why this unit test uses {@link DirtiesContext}.
+ * Refer to spring-projects/spring-framework#26196 .
+ */
+ @DirtiesContext
+ @Test
+ public void testOneOffJob() throws Exception {
+ String contentAsString = mockMvc.perform(
+ MockMvcRequestBuilders.get("/execute/manualScriptJob")
+ .characterEncoding(StandardCharsets.UTF_8))
+ .andDo(MockMvcResultHandlers.print())
+ .andExpectAll(
+ MockMvcResultMatchers.status().isOk(),
+ MockMvcResultMatchers.content().encoding(StandardCharsets.UTF_8))
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ assertThat(contentAsString, is("{\"msg\":\"OK\"}"));
+ }
+}
diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java
new file mode 100644
index 0000000000..64a6be94ed
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java
@@ -0,0 +1,52 @@
+/*
+ * 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.controller;
+
+import org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@RestController
+public class OneOffJobController {
+
+ private static final String RES_TEXT = "{\"msg\":\"OK\"}";
+
+ @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+ @Autowired
+ @Qualifier("manualScriptJobBean")
+ private ObjectProvider manualScriptJobProvider;
+
+ /**
+ * Execute manual script job.
+ *
+ * @return a String
+ */
+ @GetMapping("/execute/manualScriptJob")
+ public String executeManualScriptJob() {
+ OneOffJobBootstrap manualScriptJob = manualScriptJobProvider.getIfAvailable();
+ Objects.requireNonNull(manualScriptJob);
+ manualScriptJob.execute();
+ manualScriptJob.shutdown();
+ return RES_TEXT;
+ }
+}
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
new file mode 100644
index 0000000000..992ca14dca
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java
@@ -0,0 +1,62 @@
+/*
+ * 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.dataflow.job.DataflowJob;
+import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.SpringBootFooRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.invoke.MethodHandles;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Component
+public class SpringBootDataflowJob implements DataflowJob {
+
+ private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ @Autowired
+ private SpringBootFooRepository springBootFooRepository;
+
+ @Override
+ public List fetchData(final ShardingContext shardingContext) {
+ logger.info("Item: {} | Time: {} | Thread: {} | {}",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "DATAFLOW FETCH");
+ return springBootFooRepository.findTodoData(shardingContext.getShardingParameter(), 10);
+ }
+
+ @Override
+ public void processData(final ShardingContext shardingContext, final List data) {
+ logger.info("Item: {} | Time: {} | Thread: {} | {}",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "DATAFLOW PROCESS");
+ data.forEach(each -> springBootFooRepository.setCompleted(each.getId()));
+ }
+}
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
new file mode 100644
index 0000000000..1185636d26
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java
@@ -0,0 +1,51 @@
+/*
+ * 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.simple.job.SimpleJob;
+import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext;
+import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.SpringBootFooRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.invoke.MethodHandles;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Component
+public class SpringBootSimpleJob implements SimpleJob {
+
+ private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ @Autowired
+ private SpringBootFooRepository springBootFooRepository;
+
+ @Override
+ public void execute(final ShardingContext shardingContext) {
+ logger.info(
+ "Item: {} | Time: {} | Thread: {} | {}",
+ shardingContext.getShardingItem(),
+ new SimpleDateFormat("HH:mm:ss").format(new Date()),
+ Thread.currentThread().getId(),
+ "SIMPLE");
+ springBootFooRepository.findTodoData(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/SpringBootFooRepository.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
new file mode 100644
index 0000000000..cafe2bb023
--- /dev/null
+++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java
@@ -0,0 +1,74 @@
+/*
+ * 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 org.springframework.stereotype.Repository;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.LongStream;
+
+@Repository
+public class SpringBootFooRepository {
+
+ private final Map data = new ConcurrentHashMap<>(300, 1);
+
+ public SpringBootFooRepository() {
+ addData(0L, 100L, "Beijing");
+ addData(100L, 200L, "Shanghai");
+ addData(200L, 300L, "Guangzhou");
+ }
+
+ private void addData(final long idFrom, final long idTo, final String location) {
+ LongStream.range(idFrom, idTo)
+ .forEachOrdered(i -> data.put(i, new Foo(i, location, Foo.Status.TODO)));
+ }
+
+ /**
+ * Find todoData.
+ * @param location location
+ * @param limit limit
+ * @return An ordered collection, where the user has precise control over where in the list each element is inserted.
+ */
+ public List findTodoData(final String location, final int limit) {
+ List result = new ArrayList<>(limit);
+ int count = 0;
+ for (Map.Entry each : data.entrySet()) {
+ Foo foo = each.getValue();
+ if (foo.getLocation().equals(location) && foo.getStatus() == Foo.Status.TODO) {
+ result.add(foo);
+ count++;
+ if (count == limit) {
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set completed.
+ * @param id id
+ */
+ public void setCompleted(final long id) {
+ data.get(id).setStatus(Foo.Status.COMPLETED);
+ }
+}
diff --git a/test/native/src/test/resources/application.yml b/test/native/src/test/resources/application.yml
new file mode 100644
index 0000000000..1a99cecae9
--- /dev/null
+++ b/test/native/src/test/resources/application.yml
@@ -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.
+#
+
+spring:
+ datasource:
+ url: jdbc:h2:mem:job_event_storage
+ driver-class-name: org.h2.Driver
+ username: sa
+ password:
+
+elasticjob:
+ tracing:
+ type: RDB
+ # `elasticjob.regCenter.serverLists` is dynamically defined in `org.apache.shardingsphere.elasticjob.test.natived.SpirngBootTest`
+ regCenter:
+ namespace: elasticjob-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
+ dataflowJob:
+ elasticJobClass: org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow.SpringBootDataflowJob
+ cron: 0/5 * * * * ?
+ shardingTotalCount: 3
+ shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou
+ scriptJob:
+ elasticJobType: SCRIPT
+ cron: 0/10 * * * * ?
+ shardingTotalCount: 3
+ props:
+ script.command.line: "echo SCRIPT Job: "
+ manualScriptJob:
+ elasticJobType: SCRIPT
+ jobBootstrapBeanName: manualScriptJobBean
+ shardingTotalCount: 9
+ props:
+ script.command.line: "echo Manual SCRIPT Job: "
+ dump:
+ port: 9888
diff --git a/test/native/src/test/resources/script/demo.sh b/test/native/src/test/resources/test-native/sh/demo.sh
similarity index 100%
rename from test/native/src/test/resources/script/demo.sh
rename to test/native/src/test/resources/test-native/sh/demo.sh