Announcement Announcement Module
Collapse
No announcement yet.
quartz job needs my dao object Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • quartz job needs my dao object

    I am trying to configure spring to autowire my quartz job but it does not appear to be working. I have my job with the following field level annotations:
    Code:
    	
    @Autowired(required=true)
        @Qualifier("addrEntryDao")
    	private AddrEntryDao addrEntryDao;
    but no matter what I do, I can't get quartz to autowire my Job. Here is how I schedule it:
    Code:
    Scheduler sched = StdSchedulerFactory.getDefaultScheduler();
    	    	
    	    	JobDetail jobDetail = new JobDetail("AddrUploadJob","default",ImportXLSJob.class);
    	    	
    	    	JobDataMap jobData =  new JobDataMap();
    	    	jobData.put(ImportXLSJob.FILE_DATA_KEY, uploadFile.getBytes());
    	    	
    	    	jobDetail.setJobDataMap(jobData);
    	    	
    	    	Date now = new Date();
    	    	Trigger trigger = TriggerUtils.makeImmediateTrigger(0, 0);
    	    	trigger.setStartTime(now);
    	    	trigger.setName(Long.toString(now.getTime()));
    	    	
    	    	sched.scheduleJob(jobDetail,trigger);
    	    	LOGGER.debug("Redirecting to Running Job List");
    			forward="redirect:/"+new SchedulingController().renderScheduledList(model)+".html";

    I'm not sure what I need to do to get spring to wire my quartz job. I know that spring can't wire my dao in because I did not get my job object from spring but I thought that spring could autowire objects even if the new keyword was used to create them. I am stuck here if there is no solution. Can someone please tell me what i need to do? I thought just anotating the jobs as @Component would do it but that does not seem to work.

  • #2
    Quartz doesn't know anything about spring. Quartz is the one that instantiates your job class when the job runs.

    This question has been answered many, many times...

    http://static.springsource.org/sprin...cheduling.html

    http://www.javaranch.com/journal/200...nd_quartz.html

    http://cse-mjmcl.cse.bris.ac.uk/blog...370280435.html

    Comment


    • #3
      at the risk of looking stupid, this approach is nor especially useful. I don't want to configure quartz inside spring and even less I don't want to have to extend non native quartz classes. Is there another way? I have resorted to trying implement my business logic in a business class annotated as a @Service. Is it possible to autowire a service class called by a quartz job. what would that look like?

      Comment


      • #4
        you could intialize the class (which starts the quartz scheduler) with the desired services autowired.
        add these services to the schedulers' context (scheduler.setContext().put(...)) before scheduling a job.

        Now inside the Job retrieve the required services/dao/.. from the context.

        if you can use the spring schedulerFactoryBean then you could directly provide these services into the schedulerContextMap map. After which if you extend your job from the quartzJobbean the properties with same bean names are autopopulated.

        If you need another additional layer of a mapper which switches between your quartz and domain related objects maybe you could template your methods to perform a mapping (with Dozer for example)

        Comment


        • #5
          Was too tired to write an explanation yesterday.
          (Would prefer approach 2 and is intuitive from approach 1)
          Here goes the example for approach 1
          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
          	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
          	xmlns:si="http://www.springframework.org/schema/tx"
          	xsi:schemaLocation="
              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
          	<context:component-scan base-package="know.quartz" />
          
          	<!-- service that needs to be called inside the job -->
          	<bean id="service" class="know.quartz.YourServiceImpl" />
          
          </beans>
          the initializing class for the scheduler

          Code:
          package know.quartz;
          
          import org.quartz.JobDetail;
          import org.quartz.Scheduler;
          import org.quartz.SchedulerException;
          import org.quartz.TriggerUtils;
          import org.quartz.impl.StdSchedulerFactory;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Service;
          
          @Service("quartzStarter")
          public class SomeInitializingService {
          
          	@Autowired
          	private YourService service;
          	
          
          	private Scheduler scheduler;
          
          	public void initializeAndStartScheduler() throws SchedulerException {
          		if(this.scheduler==null){
          			this.scheduler = StdSchedulerFactory.getDefaultScheduler();	
          		}
          		this.scheduler.getContext().put("aService", service);
          		this.scheduler.start();
          	}
          
          	public void scheduleAJob(JobDetail aJobDetail) throws SchedulerException {
          		scheduler.scheduleJob(aJobDetail, TriggerUtils
          				.makeImmediateTrigger("new",0, 0));
          	}
          
          }
          An example Job Class that gets the service from the context.
          Code:
          package know.quartz;
          
          import org.quartz.Job;
          import org.quartz.JobExecutionContext;
          import org.quartz.JobExecutionException;
          import org.quartz.SchedulerException;
          
          public class YourJob implements Job {
          
          	@Override
          	public void execute(JobExecutionContext context) throws JobExecutionException {
          		try {
          			YourService service =(YourService)context.getScheduler().getContext().get("aService");
          			service.doSomething();
          		} catch (SchedulerException e) {
          		}
          
          	}
          
          }
          A class to test it.

          Code:
          package know.quartz;
          
          import org.quartz.JobDetail;
          import org.quartz.SchedulerException;
          import org.springframework.context.support.ClassPathXmlApplicationContext;
          
          public class QuartzWorkflowExplainer {
          	
          	public static void main(String args[]) throws SchedulerException, InterruptedException {
          		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
          		//a one time initialization.Choose ur strategy
          		SomeInitializingService service=(SomeInitializingService)context.getBean("quartzStarter");
          		service.initializeAndStartScheduler();
          		
          		JobDetail jobDetail = new JobDetail("us", "them", YourJob.class);
          		service.scheduleAJob(jobDetail);
          		
          	}
          
          }

          Comment


          • #6
            initializeAndStartScheduler method in SomeInitializingService could be done in a largely better way as would have rightly noticed .The explanations were just to demonstrate the usage

            Comment

            Working...
            X