Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Quartz中使用property/xml文件动态添加脚本作为作业_Java_Quartz Scheduler - Fatal编程技术网

Java 在Quartz中使用property/xml文件动态添加脚本作为作业

Java 在Quartz中使用property/xml文件动态添加脚本作为作业,java,quartz-scheduler,Java,Quartz Scheduler,场景:我想创建一个调度程序应用程序,它应该按照定义的调度运行shell脚本。为了简单起见,我希望用户在我的应用程序将使用的一些外部文件(properties/xml)中添加脚本名和执行时间。目前,我计划在Linux服务器上作为后台进程运行此应用程序。在未来,我们可能会将其作为一个web应用程序 我迄今为止的尝试: 为此,我遇到了xmlschedulingdataprocessorplugin,但它要求用户将作业作为Java代码编写,然后将其添加到XML文件中 我发现目前不起作用 请提供一些有用的

场景:我想创建一个调度程序应用程序,它应该按照定义的调度运行shell脚本。为了简单起见,我希望用户在我的应用程序将使用的一些外部文件(properties/xml)中添加脚本名和执行时间。目前,我计划在Linux服务器上作为后台进程运行此应用程序。在未来,我们可能会将其作为一个web应用程序

我迄今为止的尝试:

  • 为此,我遇到了
    xmlschedulingdataprocessorplugin
    ,但它要求用户将作业作为Java代码编写,然后将其添加到XML文件中
  • 我发现目前不起作用
  • 请提供一些有用的quartz API,帮助我实现此目的

    更新:

    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,触发器)


    您可以按如下方式执行操作

    首先,我们也需要这样做

  • 创建java应用程序,该应用程序具有一个计划作业,该作业将在 某个时间间隔一个propery/xml文件,该文件将提供 需要在什么时间执行哪个shell_文件
  • 当程序的计划作业读取该属性/xml文件并获取 资料如下:

     2.1. Shell-Script-File-Name
     2.2. Timing at what time that script needs to be execute.
    
  • 通过上面(步骤2)读取的信息,在it的帮助下,完成此作业 将创建新的独立作业,该作业完全负责执行 特定时间的shell脚本。(该时间将是您的工作时间,即 从propery/xml文件中读取)。也要注意,它应该是一次性的(根据您的要求)

  • 上述步骤重复执行,直到此作业读取全部信息,每次都将生成一个新作业

  • 如果用户在一段时间后编辑/更新/向property/xml文件中添加新行,则此java程序的计划作业将是只读的 新的变化和相应的做如上所述

  • 为了更好地理解,您可以看到下图

    出于调度目的,您可以为
    调度作业设置
    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添加一些通用上下文。触发器是独立的,在读取文件的块中构造触发器。我想在运行时添加新作业,这是简单的执行部分。