3

I use Spring 4.0 and have moved a project from xml to java-config, and everything works except accessing an @Service("scheduleService") annotated class from QuartzJobBean.executeInternal.

The xml-bit I had to make it work was:

<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="schedulerContextAsMap">
        <map>
            <entry key="scheduleService" value-ref="scheduleService" />
            <entry key="knxUtil" value-ref="knxUtil" />
        </map>
    </property>
</bean>

Then, for scheduling the Job inside @Service("scheduleService") I used:

JobBuilder jobBuilder = JobBuilder.newJob(ScheduledActionRunner.class)

Furthermore, to actually execute the Job I had it working like this:

@Component
public class ScheduledActionRunner extends QuartzJobBean {

    private KNXUtil         knxUtil;

    private ScheduleService scheduleService;

    public ScheduledActionRunner() {
    }

    @Autowired
    public void setScheduleService(ScheduleService scheduleService) {
        this.scheduleService = scheduleService;
    }

    @Autowired
    public void setKnxUtil(KNXUtil knxUtil) {
        this.knxUtil = knxUtil;
    }

    @Override
    public void executeInternal(JobExecutionContext context) throws JobExecutionException {

        JobDataMap jobDataMap = context.getMergedJobDataMap();

        String scheduleId = jobDataMap.getString("scheduleId");

        Schedule schedule = scheduleService.get(scheduleId);

        Set<ScheduledAction> actions = schedule.getScheduledActions();

        for (ScheduledAction scheduledAction : actions) {
            scheduledAction.getAction().execute(logger, knxUtil);
        }

    }

As mentioned above, all this used to work while using xml-configuration.

Now, with java-config, it fails with NullPointerException at scheduleService.get(scheduleId);

For java-configuration I set up the SchedulerFactoryBean like this:

@Configuration
@PropertySource(value = "classpath:properties.${target_env:dev}.properties")
@ComponentScan(basePackages = { "com.example.smart" }
public class SpringRootApplication {

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private KNXUtil         knxUtil;

    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {

        SchedulerFactoryBean bean = new SchedulerFactoryBean();

        Map<String, Object> schedulerContextAsMap = new HashMap<String, Object>();
        schedulerContextAsMap.put("scheduleService", scheduleService);
        schedulerContextAsMap.put("knxUtil", knxUtil);

        bean.setSchedulerContextAsMap(schedulerContextAsMap);

        return bean;
    }
}

How can I insert the reference to scheduleService inside the schedulerContextAsMap using java-config?

yglodt
  • 13,807
  • 14
  • 91
  • 127
  • You are mixing two techniques here: it's either `QuartzJobBean` or injection via context but not both. see [QuartzJobBean javadoc](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/quartz/QuartzJobBean.html) –  Jan 05 '14 at 09:37

1 Answers1

3

I found the answer here: https://stackoverflow.com/a/17394905/272180

The solution was to remove bean.setSchedulerContextAsMap(schedulerContextAsMap) when setting up SchedulerFactoryBean, and modify executeInternal as follows:

@Autowired
private KNXUtil         knxUtil;

@Autowired
private ScheduleService scheduleService;

@Override
public void executeInternal(JobExecutionContext context) throws JobExecutionException {

    // Adding this autowires everything as needed
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

    JobDataMap jobDataMap = context.getMergedJobDataMap();

    String scheduleId = jobDataMap.getString("scheduleId");

    Schedule schedule = scheduleService.get(scheduleId);

    Set<ScheduledAction> actions = schedule.getScheduledActions();

    for (ScheduledAction scheduledAction : actions) {
        scheduledAction.getAction().execute(logger, knxUtil);
    }

}

This also simplifies the code since the @Autowired annotated setters are not needed anymore.

Community
  • 1
  • 1
yglodt
  • 13,807
  • 14
  • 91
  • 127
  • I think you don't even need the schedulerContextAsMap property, since you are using processInjectionBasedOnCurrentContext – Diego Plentz Aug 14 '14 at 17:38