1 package com.atlassian.scheduler.quartz2;
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.Scheduler;
10 import org.quartz.SchedulerException;
11 import org.quartz.simpl.SimpleJobFactory;
12 import org.quartz.spi.JobFactory;
13 import org.quartz.spi.TriggerFiredBundle;
14
15 import static com.atlassian.util.concurrent.Assertions.notNull;
16
17
18
19
20
21
22 class Quartz2JobFactory extends SimpleJobFactory implements JobFactory {
23 private final AbstractSchedulerService schedulerService;
24 private final RunMode schedulerRunMode;
25
26 Quartz2JobFactory(AbstractSchedulerService schedulerService, RunMode schedulerRunMode) {
27 this.schedulerService = notNull("schedulerService", schedulerService);
28 this.schedulerRunMode = notNull("schedulerRunMode", schedulerRunMode);
29 }
30
31 @Override
32 public Job newJob(final TriggerFiredBundle bundle, final Scheduler scheduler) throws SchedulerException {
33 final JobDetail jobDetail = bundle.getJobDetail();
34 if (Quartz2Job.class.equals(jobDetail.getJobClass())) {
35 return new Quartz2Job(schedulerService, schedulerRunMode, bundle);
36 }
37 return new ClassLoaderProtectingWrappedJob(super.newJob(bundle, scheduler), schedulerService);
38 }
39
40
41 static class ClassLoaderProtectingWrappedJob implements Job {
42 private final Job delegate;
43 private final AbstractSchedulerService service;
44
45 ClassLoaderProtectingWrappedJob(Job delegate, AbstractSchedulerService service) {
46 this.service = service;
47 this.delegate = notNull("delegate", delegate);
48 }
49
50 @Override
51 public void execute(JobExecutionContext context) throws JobExecutionException {
52 service.preJob();
53 final Thread thd = Thread.currentThread();
54 final ClassLoader originalClassLoader = thd.getContextClassLoader();
55 try {
56 thd.setContextClassLoader(delegate.getClass().getClassLoader());
57 delegate.execute(context);
58 } finally {
59 thd.setContextClassLoader(originalClassLoader);
60 service.postJob();
61 }
62 }
63 }
64 }