Java 在Quartz中使用property/xml文件动态添加脚本作为作业
场景:我想创建一个调度程序应用程序,它应该按照定义的调度运行shell脚本。为了简单起见,我希望用户在我的应用程序将使用的一些外部文件(properties/xml)中添加脚本名和执行时间。目前,我计划在Linux服务器上作为后台进程运行此应用程序。在未来,我们可能会将其作为一个web应用程序 我迄今为止的尝试:Java 在Quartz中使用property/xml文件动态添加脚本作为作业,java,quartz-scheduler,Java,Quartz Scheduler,场景:我想创建一个调度程序应用程序,它应该按照定义的调度运行shell脚本。为了简单起见,我希望用户在我的应用程序将使用的一些外部文件(properties/xml)中添加脚本名和执行时间。目前,我计划在Linux服务器上作为后台进程运行此应用程序。在未来,我们可能会将其作为一个web应用程序 我迄今为止的尝试: 为此,我遇到了xmlschedulingdataprocessorplugin,但它要求用户将作业作为Java代码编写,然后将其添加到XML文件中 我发现目前不起作用 请提供一些有用的
xmlschedulingdataprocessorplugin
,但它要求用户将作业作为Java代码编写,然后将其添加到XML文件中李>
public class CronTriggerExample {
public static void main(String[] args) throws Exception {
String[] a = {"script1.sh:0/10 * * * * ?", "script2.sh:0/35 * * * * ?"};
for (String config : a) {
String[] attr = config.split(":");
System.out.println("Iterating for : "+attr[0]);
JobKey jobKey = new JobKey(attr[0], attr[0]);
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity(attr[0], attr[0])
.withSchedule(CronScheduleBuilder.cronSchedule(attr[1]))
.build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.getContext().put("val", config);
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity(jobKey).build();
scheduler.start();
scheduler.scheduleJob(job, trigger);
System.out.println("=======================");
}
}
}
我的HelloJob课程:
public class HelloJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
String objectFromContext = null;
Date date = new Date();
try {
SchedulerContext schedulerContext = context.getScheduler().getContext();
objectFromContext = (String) schedulerContext.get("val");
} catch (SchedulerException ex) {
ex.printStackTrace();
}
System.out.println("Triggered "+objectFromContext+" at: "+date);
}
}
输出:
Iterating for : script1.sh
log4j:WARN No appenders could be found for logger (org.quartz.impl.StdSchedulerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
=======================
Iterating for : script2.sh
=======================
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:21:50 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:00 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:00 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:10 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:20 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:30 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:35 IST 2016
Triggered script2.sh:0/35 * * * * ? at: Mon Apr 18 12:22:40 IST 2016
我错过了什么?我尝试为每个迭代创建新作业,并将脚本名称指定为
JobExecutionContext
下面的教程帮助您安排shell脚本
利用
Runtime.getRuntime().exec("sh shellscript.sh");
您可以运行shell脚本。我将采用以下方法:
- 您创建一个类JobShellRunner,它将从quartz实现作业接口:
}public class JobShellRunner implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // here you take need information about the shell script you need to run, from the context and run the shell script }
- 读取属性文件(我想这里有关于运行哪个shell脚本及其时间表信息的可用信息)。对于所需的每个信息,您将创建其上下文和触发器:
JobKey jobKey = new JobKey("jobShellRunner", "group1"); // put in the job key need information about shell script (path, etc) JobDetail jobA = JobBuilder.newJob(JobShellRunner.class) .withIdentity(jobKey).build();
- 然后是触发器(请注意,在cron表达式上,您应该使用从属性文件读取的表达式来完成): 触发器=触发器生成器 .newTrigger() .withIdentity(“dummyTriggerName1”、“group1”) .时间表( CronScheduleBuilder.cronSchedule(“0/5****?”) .build()
- 然后安排工作 scheduleJob(jobA,触发器)
2.1. Shell-Script-File-Name
2.2. Timing at what time that script needs to be execute.
调度作业设置spring quartz API
在这里,我将给你一个小的位伪代码
public class JobA implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
// continues read property/xml file untill while file not read
// based upon above read info. generate new job(one time only) at runtime which has capability to execute shell script
// shell script can be execute by java program by this ,
// Runtime.getRuntime().exec("sh /full-path/shell_script_name.sh");
}
}
............
public class CronTriggerExample {
public static void main( String[] args ) throws Exception
{
JobKey jobKeyA = new JobKey("jobA", "group1");
JobDetail jobA = JobBuilder.newJob(JobA.class)
.withIdentity(jobKeyA).build();
Trigger trigger1 = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName1", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?")) // you can set here your comfortable job time...
.build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(jobA, trigger1);
}
}
因此,这是我在这里所相信和表达的想法,根据您的要求,这是最合适的。您是否考虑过简单地使用Cron和/或Java应用程序解析xml来更新crontab?我怀疑这是解决方案。对于具有diff触发器的3个不同脚本,我必须创建3个diff类,然后将它们传递给JobBuilder.newJob
,然后相应地附加触发器。外部文件中有脚本名称,因此将其作为键放在jobKey中,然后使用JobExecutionContext访问它。因此,您不必创建3个不同的类。您可以使用JobKey和JobExecutionContext添加一些通用上下文。触发器是独立的,在读取文件的块中构造触发器。我想在运行时添加新作业,这是简单的执行部分。