I'm developing a Javaee7 webapp to run over Wildfly 10.0.0, using CDI for dependency injection, and want to schedule some jobs with Quartz. This is the class that schedules the job:
@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);
}
}
}
This is the custom JobFactory to allow using CDI on Quartz:
@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);
}
}
And this is the Job:
@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);
}
}
}
When I try to deploy the war file, I get this error:
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)
This is the content of 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>
Any idea of what's going wrong?
The problem is that you're using bean-discovery-mode="annotated"
but not providing bean defining annotations on your classes.
Ideally, @Named
is only used for UI type interaction, and few other vendor specific capabilities. Its a qualifier. To make this work, I would annotate it using @ApplicationScoped
instead of @Named
.
Reference within the CDI Spec: http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_defining_annotations