public void executeJob(final ScheduledJobDetail scheduledJobDetail, String triggerType) {
    try {
      final JobDataMap jobDataMap = new JobDataMap();
      if (triggerType == null) {
        triggerType = SchedulerServiceConstants.TRIGGER_TYPE_APPLICATION;
      }
      jobDataMap.put(SchedulerServiceConstants.TRIGGER_TYPE_REFERENCE, triggerType);
      jobDataMap.put(
          SchedulerServiceConstants.TENANT_IDENTIFIER,
          ThreadLocalContextUtil.getTenant().getTenantIdentifier());
      final String key = scheduledJobDetail.getJobKey();
      final JobKey jobKey = constructJobKey(key);
      final String schedulerName = getSchedulerName(scheduledJobDetail);
      final Scheduler scheduler = this.schedulers.get(schedulerName);
      if (scheduler == null || !scheduler.checkExists(jobKey)) {
        final JobDetail jobDetail = createJobDetail(scheduledJobDetail);
        final String tempSchedulerName = "temp" + scheduledJobDetail.getId();
        final Scheduler tempScheduler =
            createScheduler(tempSchedulerName, 1, schedulerJobListener, schedulerStopListener);
        tempScheduler.addJob(jobDetail, true);
        jobDataMap.put(SchedulerServiceConstants.SCHEDULER_NAME, tempSchedulerName);
        this.schedulers.put(tempSchedulerName, tempScheduler);
        tempScheduler.triggerJob(jobDetail.getKey(), jobDataMap);
      } else {
        scheduler.triggerJob(jobKey, jobDataMap);
      }

    } catch (final Exception e) {
      final String msg = "Job execution failed for job with id:" + scheduledJobDetail.getId();
      logger.error(msg, e);
      throw new PlatformInternalServerException(
          "error.msg.sheduler.job.execution.failed", msg, scheduledJobDetail.getId());
    }
  }
 private String getSchedulerName(final ScheduledJobDetail scheduledJobDetail) {
   final StringBuilder sb = new StringBuilder(20);
   final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
   sb.append(SchedulerServiceConstants.SCHEDULER).append(tenant.getId());
   if (scheduledJobDetail.getSchedulerGroup() > 0) {
     sb.append(SchedulerServiceConstants.SCHEDULER_GROUP)
         .append(scheduledJobDetail.getSchedulerGroup());
   }
   return sb.toString();
 }
 public void rescheduleJob(final ScheduledJobDetail scheduledJobDetail) {
   try {
     final String jobIdentity = scheduledJobDetail.getJobKey();
     final JobKey jobKey = constructJobKey(jobIdentity);
     final String schedulername = getSchedulerName(scheduledJobDetail);
     final Scheduler scheduler = this.schedulers.get(schedulername);
     if (scheduler != null) {
       scheduler.deleteJob(jobKey);
     }
     scheduleJob(scheduledJobDetail);
     this.schedularWritePlatformService.saveOrUpdate(scheduledJobDetail);
   } catch (final Throwable throwable) {
     final String stackTrace = getStackTraceAsString(throwable);
     scheduledJobDetail.updateErrorLog(stackTrace);
     this.schedularWritePlatformService.saveOrUpdate(scheduledJobDetail);
   }
 }
 private JobDetail createJobDetail(final ScheduledJobDetail scheduledJobDetail) throws Exception {
   final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
   final ClassMethodNamesPair jobDetails =
       CronMethodParser.findTargetMethodDetails(scheduledJobDetail.getJobName());
   if (jobDetails == null) {
     throw new IllegalArgumentException(
         "Code has no @CronTarget with this job name (@see JobName); seems like DB/code are not in line: "
             + scheduledJobDetail.getJobName());
   }
   final Object targetObject = getBeanObject(Class.forName(jobDetails.className));
   final MethodInvokingJobDetailFactoryBean jobDetailFactoryBean =
       new MethodInvokingJobDetailFactoryBean();
   jobDetailFactoryBean.setName(scheduledJobDetail.getJobName() + "JobDetail" + tenant.getId());
   jobDetailFactoryBean.setTargetObject(targetObject);
   jobDetailFactoryBean.setTargetMethod(jobDetails.methodName);
   jobDetailFactoryBean.setGroup(scheduledJobDetail.getGroupName());
   jobDetailFactoryBean.setConcurrent(false);
   jobDetailFactoryBean.afterPropertiesSet();
   return jobDetailFactoryBean.getObject();
 }
 @PostConstruct
 public void loadAllJobs() {
   final List<MifosPlatformTenant> allTenants = this.tenantDetailsService.findAllTenants();
   for (final MifosPlatformTenant tenant : allTenants) {
     ThreadLocalContextUtil.setTenant(tenant);
     final List<ScheduledJobDetail> scheduledJobDetails =
         this.schedularWritePlatformService.retrieveAllJobs();
     for (final ScheduledJobDetail jobDetails : scheduledJobDetails) {
       scheduleJob(jobDetails);
       jobDetails.updateTriggerMisfired(false);
       this.schedularWritePlatformService.saveOrUpdate(jobDetails);
     }
     final SchedulerDetail schedulerDetail =
         this.schedularWritePlatformService.retriveSchedulerDetail();
     if (schedulerDetail.isResetSchedulerOnBootup()) {
       schedulerDetail.updateSuspendedState(false);
       this.schedularWritePlatformService.updateSchedulerDetail(schedulerDetail);
     }
   }
 }
 private Trigger createTrigger(
     final ScheduledJobDetail scheduledJobDetails, final JobDetail jobDetail) {
   try {
     final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
     final CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
     cronTriggerFactoryBean.setName(scheduledJobDetails.getJobName() + "Trigger" + tenant.getId());
     cronTriggerFactoryBean.setJobDetail(jobDetail);
     final JobDataMap jobDataMap = new JobDataMap();
     jobDataMap.put(SchedulerServiceConstants.TENANT_IDENTIFIER, tenant.getTenantIdentifier());
     cronTriggerFactoryBean.setJobDataMap(jobDataMap);
     final TimeZone timeZone = TimeZone.getTimeZone(tenant.getTimezoneId());
     cronTriggerFactoryBean.setTimeZone(timeZone);
     cronTriggerFactoryBean.setGroup(scheduledJobDetails.getGroupName());
     cronTriggerFactoryBean.setCronExpression(scheduledJobDetails.getCronExpression());
     cronTriggerFactoryBean.setPriority(scheduledJobDetails.getTaskPriority());
     cronTriggerFactoryBean.afterPropertiesSet();
     return cronTriggerFactoryBean.getObject();
   } catch (ParseException e) {
     throw new RuntimeException(e);
   }
 }
 private Scheduler getScheduler(final ScheduledJobDetail scheduledJobDetail) throws Exception {
   final String schedulername = getSchedulerName(scheduledJobDetail);
   Scheduler scheduler = this.schedulers.get(schedulername);
   if (scheduler == null) {
     int noOfThreads = SchedulerServiceConstants.DEFAULT_THREAD_COUNT;
     if (scheduledJobDetail.getSchedulerGroup() > 0) {
       noOfThreads = SchedulerServiceConstants.GROUP_THREAD_COUNT;
     }
     scheduler = createScheduler(schedulername, noOfThreads, schedulerJobListener);
     this.schedulers.put(schedulername, scheduler);
   }
   return scheduler;
 }
 private void scheduleJob(final ScheduledJobDetail scheduledJobDetails) {
   if (!scheduledJobDetails.isActiveSchedular()) {
     scheduledJobDetails.updateNextRunTime(null);
     scheduledJobDetails.updateCurrentlyRunningStatus(false);
     return;
   }
   try {
     final JobDetail jobDetail = createJobDetail(scheduledJobDetails);
     final Trigger trigger = createTrigger(scheduledJobDetails, jobDetail);
     final Scheduler scheduler = getScheduler(scheduledJobDetails);
     scheduler.scheduleJob(jobDetail, trigger);
     scheduledJobDetails.updateJobKey(getJobKeyAsString(jobDetail.getKey()));
     scheduledJobDetails.updateNextRunTime(trigger.getNextFireTime());
     scheduledJobDetails.updateErrorLog(null);
   } catch (final Throwable throwable) {
     scheduledJobDetails.updateNextRunTime(null);
     final String stackTrace = getStackTraceAsString(throwable);
     scheduledJobDetails.updateErrorLog(stackTrace);
     logger.error("Could not schedule job: " + scheduledJobDetails.getJobName(), throwable);
   }
   scheduledJobDetails.updateCurrentlyRunningStatus(false);
 }
 @Override
 public void startScheduler() {
   final SchedulerDetail schedulerDetail =
       this.schedularWritePlatformService.retriveSchedulerDetail();
   if (schedulerDetail.isSuspended()) {
     schedulerDetail.updateSuspendedState(false);
     this.schedularWritePlatformService.updateSchedulerDetail(schedulerDetail);
     if (schedulerDetail.isExecuteInstructionForMisfiredJobs()) {
       final List<ScheduledJobDetail> scheduledJobDetails =
           this.schedularWritePlatformService.retrieveAllJobs();
       for (final ScheduledJobDetail jobDetail : scheduledJobDetails) {
         if (jobDetail.isTriggerMisfired()) {
           if (jobDetail.isActiveSchedular()) {
             executeJob(jobDetail, SchedulerServiceConstants.TRIGGER_TYPE_CRON);
           }
           final String schedulerName = getSchedulerName(jobDetail);
           final Scheduler scheduler = this.schedulers.get(schedulerName);
           if (scheduler != null) {
             final String key = jobDetail.getJobKey();
             final JobKey jobKey = constructJobKey(key);
             try {
               final List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
               for (final Trigger trigger : triggers) {
                 if (trigger.getNextFireTime() != null
                     && trigger.getNextFireTime().after(jobDetail.getNextRunTime())) {
                   jobDetail.updateNextRunTime(trigger.getNextFireTime());
                 }
               }
             } catch (final SchedulerException e) {
               logger.error(e.getMessage(), e);
             }
           }
           jobDetail.updateTriggerMisfired(false);
           this.schedularWritePlatformService.saveOrUpdate(jobDetail);
         }
       }
     }
   }
 }