Results 1 to 3 of 3

Thread: Manually creating a MethodInvokingJobDetailFactoryBean?

  1. #1

    Question Manually creating a MethodInvokingJobDetailFactoryBean?

    We have an enterprise application that uses a Quartz Scheduler to invoke CronJobs. Spring has the ability to create the scheduler and invoke the cronjobs via XML configuration, unfortunately, we need our clients to be able to modify these jobs via our application. Also, we want to read & write the jobs from the database using our Hibernate Layer.

    So, what we have is Spring set to startup quartz using the xml config, then in our WebContextLoaderListener we have an initialize method which reads the jobs from the DB and creates the CronJobs. The jobs are part of our action layer (old hangover from Struts), and need to call specific methods, so we are trying to manually instantiate MethodInvokingJobDetailFactoryBeans.

    Everything seems to startup fine, and we can manipulate the jobs on the fly while persisting the changes to the DB (in case of server restart), but when the scheduler runs, we get a "IllegalArgumentException: Target method must not be non-static without a target" exception.

    Any ideas? (Besides, use the examples.. unless you can point me to an example of Sprig creating the jobs by accessing the database via Hibernate Objects)

    I figure I'm missing a step in the MethodInvokingJobDetailFactoryBean creation, I just can't figure out what it is...


    XML Config:

    Code:
    <bean id="Scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="autoStartup">
    		<value>false</value> <!-- RuleManager should be the one starting the Scheduler -->
    	</property>
    	<property name="schedulerName">
    		<value>ACISScheduler</value>
    	</property>
    	<property name="waitForJobsToCompleteOnShutdown">
    		<value>true</value>
    	</property>
    </bean>


    Job/Trigger Creation:

    Code:
    Scheduler scheduler = SpringContext.getInstance().getScheduler();
    List<CronJob> cronJobList = SpringContext.getInstance().getCronJobLogic().list();
    try
    {
    	scheduler.start();
    	for (CronJob cronJob : cronJobList)
    	{
    		try
    		{
    			MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
    			jobDetail.setTargetMethod(cronJob.getTargetMethod());
    			jobDetail.setTargetClass(Class.forName(cronJob.getTargetObject()));
    			jobDetail.setName(cronJob.toString());
    			jobDetail.afterPropertiesSet();
    			CronTrigger cronTrigger = new CronTrigger(cronJob.getTriggerName(), cronJob.getGroupName(), cronJob.getExpression());
    			scheduler.scheduleJob((JobDetail)jobDetail.getObject(), cronTrigger);
    		}
    		catch (Exception e)
    		{
    			logger.error(e.getMessage(), e);
    		}
    	}
    }
    catch(SchedulerException se)
    {
    	logger.error(se.getMessage(), se);
    }



    Thanks,


    /Christien
    Last edited by thecatwhisperer; Dec 17th, 2008 at 01:14 PM. Reason: cleanup

  2. #2

    Default

    Allright, So I figured it out, and it is mainly me not understanding how th object is supposed to be initialized (better documentation would help though:P ).

    First of all, I need to be setting the Target Object, not the Class, and second (and this issue isn't shown, I needed to initialize the object passed in via the Spring Context...)

    Begin Code:

    Code:
    Scheduler scheduler = SpringContext.getInstance().getScheduler();
    List<CronJob> cronJobList = SpringContext.getInstance().getCronJobLogic().list();
    try
    {
    	scheduler.start();
    	for (CronJob cronJob : cronJobList)
    	{
    		try
    		{
    			MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
    			jobDetail.setTargetMethod(cronJob.getTargetMethod());
    			jobDetail.setTargetObject(SpringContext.getInstance().getApplicationContext().getBean(cronJob.getTargetObject()));
    			jobDetail.setName(cronJob.toString());
    			jobDetail.afterPropertiesSet();
    			CronTrigger cronTrigger = new CronTrigger(cronJob.getTriggerName(), cronJob.getGroupName(), cronJob.getExpression());
    			scheduler.scheduleJob((JobDetail)jobDetail.getObject(), cronTrigger);
    		}
    		catch (Exception e)
    		{
    			logger.error(e.getMessage(), e);
    		}
    	}
    }
    catch(SchedulerException se)
    {
    	logger.error(se.getMessage(), se);
    }


    End Code:

    BTW, the list of cron jobs come from our Hibernate Layer. And yes, the name "CronJob" is probably a poor naming choice.

  3. #3

    Default Manaully creating a MethodInvokingJobDetailFactoryBean

    I wanted to schedule a job, with parameters, on demand in Java. The following example shows how I did this.

    BEGIN CODE

    XML

    <bean id="scheduler" class="org.springframework.scheduling.quartz.Sched ulerFactoryBean" scope="prototype">
    <property name="autoStartup" value="false"/>
    <property name="waitForJobsToCompleteOnShutdown" value="true"/>
    </bean>

    JAVA

    private class exampleClass {

    private long exampleValue;

    public exampleClass( long value ){
    this.exampleValue = value;
    }

    public void exampleMethod() {
    exampleValue++;
    }

    public long getValue(){ return exampleValue; }
    }

    @Autowired
    StdScheduler scheduler;

    @Test
    public void testScheduleTriggerToInvokeAMethod() {
    System.out.println("testScheduleTriggerToInvokeAMe thod");
    try {

    MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
    exampleClass example = new exampleClass( 0 );
    jobDetail.setTargetObject( example );
    jobDetail.setTargetMethod("exampleMethod");
    jobDetail.setName("example");
    jobDetail.setGroup("test");
    jobDetail.setConcurrent(false);
    jobDetail.afterPropertiesSet();


    SimpleTriggerBean trigger = new SimpleTriggerBean();
    trigger.setBeanName("Example");
    trigger.setJobDetail( (JobDetail)(jobDetail.getObject()) );
    trigger.setRepeatCount( 3 );
    trigger.setRepeatInterval(100);
    trigger.setStartDelay( 0 );
    trigger.afterPropertiesSet();

    scheduler.start();
    scheduler.scheduleJob( (JobDetail)(jobDetail.getObject()), trigger );

    Thread.sleep( 1000 );

    assertEquals( 4, example.getValue() );

    } catch (InterruptedException ex) {
    //complain
    } catch (ClassNotFoundException ex) {
    //complain
    } catch (NoSuchMethodException ex) {
    //complain
    } catch (ParseException ex) {
    //complain
    } catch (SchedulerException ex) {
    //complain
    }
    }

    END CODE

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •