jakarta-ee - 用于将 Quartz 与 CDI 一起使用的自定义 CDJobFactory

标签 jakarta-ee quartz-scheduler cdi

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

@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);
        }
    }
}

这是允许在 Quartz 上使用 CDI 的自定义 JobFactory:
@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);
  }
}

这就是工作:
@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);
        }
    }
}

当我尝试部署 war 文件时,我收到此错误:
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)

这是 beans.xml 的内容
 <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.2" bean-discovery-mode="annotated">

</beans>

知道出了什么问题吗?

最佳答案

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

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

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

关于jakarta-ee - 用于将 Quartz 与 CDI 一起使用的自定义 CDJobFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37100811/

相关文章:

java - 处理 JavaServer Faces 的 url 映射的标准方法是什么?

java - ActiveMQ - 创建新主题 session 时出现安全异常

Java Quartz Scheduler 我的配置存在错误或问题

dependency-injection - 你可以在持久实体中使用依赖注入(inject)吗?

session - JSF2 + CDI @Produces 保持旧的 session 状态

java - Weld 和测试 jar

jakarta-ee - 从头开始的 EJB 模块

jakarta-ee - 表达式语言 lambda 类型推断

java - Quartz 调度程序无法启动 cron 作业

java - 无法在 quartz 中运行作业,因为非法访问而出现异常