View Javadoc

1   package com.atlassian.scheduler.quartz1;
2   
3   import com.atlassian.scheduler.config.RunMode;
4   import com.atlassian.scheduler.core.AbstractSchedulerService;
5   import org.quartz.Job;
6   import org.quartz.JobDetail;
7   import org.quartz.JobExecutionContext;
8   import org.quartz.JobExecutionException;
9   import org.quartz.SchedulerException;
10  import org.quartz.simpl.SimpleJobFactory;
11  import org.quartz.spi.JobFactory;
12  import org.quartz.spi.TriggerFiredBundle;
13  
14  import static com.atlassian.util.concurrent.Assertions.notNull;
15  
16  /**
17   * Assigned to the real scheduler so that we can escape the Quartz-centric world.
18   *
19   * @since v1.0
20   */
21  class Quartz1JobFactory extends SimpleJobFactory implements JobFactory {
22      private final AbstractSchedulerService schedulerService;
23      private final RunMode schedulerRunMode;
24  
25      Quartz1JobFactory(AbstractSchedulerService schedulerService, RunMode schedulerRunMode) {
26          this.schedulerService = notNull("schedulerService", schedulerService);
27          this.schedulerRunMode = notNull("schedulerRunMode", schedulerRunMode);
28      }
29  
30      @Override
31      public Job newJob(final TriggerFiredBundle bundle) throws SchedulerException {
32          final JobDetail jobDetail = bundle.getJobDetail();
33          if (Quartz1Job.class.equals(jobDetail.getJobClass())) {
34              return new Quartz1Job(schedulerService, schedulerRunMode, bundle);
35          }
36          return new ClassLoaderProtectingWrappedJob(super.newJob(bundle), schedulerService);
37      }
38  
39      // SCHEDULER-11: Ensure that the Job runs with its own class loader set as the thread's CCL
40      static class ClassLoaderProtectingWrappedJob implements Job {
41          private final Job delegate;
42          private final AbstractSchedulerService service;
43  
44          ClassLoaderProtectingWrappedJob(Job delegate, AbstractSchedulerService service) {
45              this.service = service;
46              this.delegate = notNull("delegate", delegate);
47          }
48  
49          @Override
50          public void execute(final JobExecutionContext context) throws JobExecutionException {
51              service.preJob();
52              final Thread thd = Thread.currentThread();
53              final ClassLoader originalClassLoader = thd.getContextClassLoader();
54              try {
55                  thd.setContextClassLoader(delegate.getClass().getClassLoader());
56                  delegate.execute(context);
57              } finally {
58                  thd.setContextClassLoader(originalClassLoader);
59                  service.postJob();
60              }
61          }
62      }
63  }