Announcement Announcement Module
Collapse
No announcement yet.
Scheduling Jobs with Quartz and Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Scheduling Jobs with Quartz and Spring

    Hello all,
    i am trying to schedule a job in my webapp using Quartz and spring.
    Background: i have defined in my applicationContext a persistenceManager, which is in charge of inserting/deleting/updating a database.
    I want to schedule a job that every time it gets fired, it inserts some data in the database; for that purpose i want to reuse the PersistenceManager already defined in applicationContext.xml.
    I have read the Chap. 18 of spring reference that refers to Quartz and spring, and i have created a BudgetJob class that extends JobDetailBean.
    code is as follows:
    <code>
    public class BudgetJob extends QuartzJobBean implements StatefulJob {

    private PersistenceManager pMgr = null;

    public void setPersistenceManager(PersistenceManager mgr) {
    System.err.println("**** BudgetJob. Setting PersistenceManager..");
    pMgr = mgr;
    }



    /*
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
    *
    * Interface.
    *
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
    */

    /**
    * <p>
    * Called by the <code>{@link org.quartz.Scheduler}</code> when a <code>{@link org.quartz.Trigger}</code>
    * fires that is associated with the <code>Job</code>.
    * </p>
    *
    * @throws JobExecutionException
    * if there is an exception while executing the job.
    */
    protected void executeInternal(JobExecutionContext context)
    throws JobExecutionException {
    System.err.println("---" + context.getJobDetail().getFullName()
    + " executing.[" + new Date() + "]");

    JobDataMap map = context.getJobDetail().getJobDataMap();
    try {
    Entry entry = (Entry)map.get(Constants.BUDGET_ENTRY);
    entry.setDate(new Date());
    System.err.println("Inserting entry:" + entry);
    if(pMgr == null){
    System.err.println("BJ. PersistenceManager isnull. getting it from jobdetail..");
    pMgr = (PersistenceManager)map.get("persistenceManager");
    } else
    System.err.println("BJ. PersistenceManager is NOT null...");
    pMgr.insert(entry);
    } catch(Exception e) {
    System.err.println(e);
    }
    }

    }
    </code>

    My applicationContext.xml is as follows
    <code>
    .......
    <bean id="persistenceManager" class="com.myapp.common.PersistenceManagerImpl">
    <property name="budgetDAO">
    <ref local="budgetDAO"/>
    </property>
    </bean>

    <bean name="budgetJob" class="org.springframework.scheduling.quartz.JobDe tailBean">
    <property name="jobClass">
    <value>com.myapp.scheduler.BudgetJob</value>
    </property>
    <property name="jobDataAsMap">
    <map>
    <entry key="persistenceManager">
    <ref bean="persistenceManager"/>
    </entry>
    </map>
    </property>

    </bean>
    .....
    </code>

    However, when my job gets executed, i receive a null pointer exception at the line where i am retrieving the persistenceManager from the JobDataMap.

    Can anyone tell me what is wrong? and how can i accomplish my goal to set the persistenceManager defined in applicationContext.xml in my BudgetJob so that i can reuse it?

    thanx in advance and regards

    marco

  • #2
    First, everything that is in Job's map must be serializable.

    How to get you dao out?
    In Job's execute method:
    SchedulerContext schedulerContext = context.getScheduler().getContext();
    BeanFactory beanFactory = (BeanFactory)schedulerContext.get("applicationCont ext");
    MyDAO myDAO = (MyDAO)beanFactory.getBean("myDAO");

    and you must have this line in applicationContext.xml with SchedulerFactoryBean definition:
    <property name="applicationContextSchedulerContextKey"><valu e>"applicationContext"</value></property>

    Comment


    • #3
      Hi,

      simply add a method setApplicationContext() in you job definition. Spring will set the application context when the job is fired.

      Code:
      public class BudgetJob extends QuartzJobBean implements StatefulJob &#123;
      private ApplicationContext applicationContext;
      ....
        public void setApplicationContext&#40;ApplicationContext appContext&#41; &#123;
          applicationContext = appContext;
        &#125;
      
        protected void executeInternal&#40;JobExecutionContext context&#41; 
           throws JobExecutionException &#123; 
            ... applicationContext.getBean&#40;...&#41;;
        &#125;

      Comment


      • #4
        JobDetailBean and Serializable requirements

        Originally posted by alesj
        First, everything that is in Job's map must be serializable.

        How to get you dao out?
        In Job's execute method:
        SchedulerContext schedulerContext = context.getScheduler().getContext();
        BeanFactory beanFactory = (BeanFactory)schedulerContext.get("applicationCont ext");
        MyDAO myDAO = (MyDAO)beanFactory.getBean("myDAO");

        and you must have this line in applicationContext.xml with SchedulerFactoryBean definition:
        <property name="applicationContextSchedulerContextKey"><valu e>"applicationContext"</value></property>
        Since the only thing that can be DI'd into the class specified by JobDetailBean are serializable objects, isn't this a major limitation in Quartz/Spring? At the moment, I'm having to use getBean as well which makes me feel uneasy since I feel as if I'm breaking the IoC pattern...?

        Comment


        • #5
          Spring Auto-wiring in Quartz jobs

          Everyone has asked me about this - A while back I have written an article on this. This is an old post but if this helps someone. Here is the link: http://www.harinair.com/2008/01/spri...f-quartz-jobs/

          Hari Gangadharan

          Comment

          Working...
          X