使用Quartz和CDI的自定义CDIJobFactory

时间:2016-05-08 14:18:02

标签: java-ee quartz-scheduler cdi

我正在开发一个Javaee7 webapp来运行Wildfly 10.0.0,使用CDI进行依赖注入,并希望使用Quartz安排一些作业。 这是安排工作的类:

def inorder(self):
    result = []
    if self.__left:
        result += self.__left.inorder()

    result.append(self.__value)

    if self.__right:
        result += self.__right.inorder()

    return result

这是允许在Quartz上使用CDI的自定义JobFactory:

@Singleton
@Startup
public class ScheduledJobsManager {

    private Scheduler scheduler;

    @Inject
    private CdiJobFactory jobFactory;

    @PostConstruct
    public void postConstruct() {
        JobDetail jobDetail = null;
        CronTrigger trigger = null;
        scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.setJobFactory(jobFactory);
        boolean scheduled = false;

        jobDetail = JobBuilder.newJob(ImagesProcessJob.class)
        .withIdentity("imageProcessJob", "mediaProxyJobs")
        .build();
        trigger = TriggerBuilder.newTrigger().withIdentity("imageProcessTrigger", "mediaProxyTriggers")
                .withSchedule(CronScheduleBuilder.cronSchedule(imageProcessScheduleStr)).build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
    }

    @PreDestroy
    public void preDestroy() {
        if (scheduler != null && scheduler.isStarted()) {
            scheduler.shutdown(false);
        }
    }
}

这是工作:

@Named
public class CdiJobFactory implements JobFactory {

  @Inject
  private BeanManager beanManager;

  @Override
  public Job newJob(TriggerFiredBundle bundle, Scheduler Scheduler) throws SchedulerException {
    JobDetail jobDetail = bundle.getJobDetail();
    Class<? extends Job> jobClazz = jobDetail.getJobClass();
    Bean<?> bean = beanManager.getBeans(jobClazz).iterator().next();
    CreationalContext<?> ctx = beanManager.createCreationalContext(bean);
    return (Job) beanManager.getReference(bean, jobClazz, ctx);
  }
}

当我尝试部署war文件时,出现此错误:

@Named
public class ImagesProcessJob  implements Job {
    @Inject
    private MyManager myManager;

    public ImagesProcessJob() {}

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            myManager.doTheJob();
        } catch(Exception e) {
            throw new JobExecutionException(e);
        }
    }
}

这是beans.xml的内容

16:03:19,524 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.deployment.unit."imageproxy.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."imageproxy.war".WeldStartService: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type CdiJobFactory with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private cat.xavisan.imaging.imageproxy.schedule.ScheduledJobsManager.jobFactory
  at cat.xavisan.imaging.imageproxy.schedule.ScheduledJobsManager.jobFactory(ScheduledJobsManager.java:0)

    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.jboss.threads.JBossThread.run(JBossThread.java:320)

知道出了什么问题?

1 个答案:

答案 0 :(得分:3)

问题在于您正在使用bean-discovery-mode="annotated"但未在类上提供定义注释的bean。

理想情况下,@Named仅用于UI类型交互,而其他供应商特定功能很少。它是一个限定词。为了完成这项工作,我会使用@ApplicationScoped而不是@Named对其进行注释。

CDI规范中的参考:http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_defining_annotations