private void unregisterJob(final String jobName) {
    try {
      scheduler.getScheduler().unscheduleJob(new TriggerKey(jobName, Scheduler.DEFAULT_GROUP));
      scheduler.getScheduler().deleteJob(new JobKey(jobName, Scheduler.DEFAULT_GROUP));
    } catch (SchedulerException e) {
      LOG.error("Could not remove job " + jobName, e);
    }

    if (ApplicationContextProvider.getBeanFactory().containsSingleton(jobName)) {
      ApplicationContextProvider.getBeanFactory().destroySingleton(jobName);
    }
  }
 private Scheduler createScheduler(
     final String name, final int noOfThreads, JobListener... jobListeners) throws Exception {
   final SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
   schedulerFactoryBean.setSchedulerName(name);
   schedulerFactoryBean.setGlobalJobListeners(jobListeners);
   final TriggerListener[] globalTriggerListeners = {globalSchedulerTriggerListener};
   schedulerFactoryBean.setGlobalTriggerListeners(globalTriggerListeners);
   final Properties quartzProperties = new Properties();
   quartzProperties.put(SchedulerFactoryBean.PROP_THREAD_COUNT, Integer.toString(noOfThreads));
   schedulerFactoryBean.setQuartzProperties(quartzProperties);
   schedulerFactoryBean.afterPropertiesSet();
   schedulerFactoryBean.start();
   return schedulerFactoryBean.getScheduler();
 }
  private void registerJob(
      final String jobName,
      final Job jobInstance,
      final String cronExpression,
      final Date startAt,
      final Map<String, Object> jobMap)
      throws SchedulerException, ParseException {

    synchronized (scheduler.getScheduler()) {
      boolean jobAlreadyRunning = false;
      for (JobExecutionContext jobCtx : scheduler.getScheduler().getCurrentlyExecutingJobs()) {
        if (jobName.equals(jobCtx.getJobDetail().getKey().getName())
            && Scheduler.DEFAULT_GROUP.equals(jobCtx.getJobDetail().getKey().getGroup())) {

          jobAlreadyRunning = true;

          LOG.debug("Job {} already running, cancel", jobCtx.getJobDetail().getKey());
        }
      }

      if (jobAlreadyRunning) {
        return;
      }
    }

    // 0. unregister job
    unregisterJob(jobName);

    // 1. Job bean
    ApplicationContextProvider.getBeanFactory().registerSingleton(jobName, jobInstance);

    // 2. JobDetail bean
    JobBuilder jobDetailBuilder =
        JobBuilder.newJob(jobInstance.getClass())
            .withIdentity(jobName)
            .usingJobData(new JobDataMap(jobMap));

    // 3. Trigger
    if (cronExpression == null && startAt == null) {
      // Jobs added with no trigger must be durable
      scheduler.getScheduler().addJob(jobDetailBuilder.storeDurably().build(), true);
    } else {
      TriggerBuilder<?> triggerBuilder;

      if (cronExpression == null) {
        triggerBuilder =
            TriggerBuilder.newTrigger()
                .withIdentity(JobNamer.getTriggerName(jobName))
                .startAt(startAt);
      } else {
        triggerBuilder =
            TriggerBuilder.newTrigger()
                .withIdentity(JobNamer.getTriggerName(jobName))
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));

        if (startAt == null) {
          triggerBuilder = triggerBuilder.startNow();
        } else {
          triggerBuilder = triggerBuilder.startAt(startAt);
        }
      }

      scheduler.getScheduler().scheduleJob(jobDetailBuilder.build(), triggerBuilder.build());
    }
  }