简体   繁体   中英

Execute Method is not invoking at scheduled time quartz+spring

I am trying to implement quartz persistent job using spring and new to this . I have implemented the Job interface in class SimpleQuartzJob. When I run the main program , Job is persisting in the the database but the execute(JobExecutionContext context) method of SimpleQuartzJob which implements Job, is not triggering at the scheduled time. I am not able to figure why this is happening.

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SimpleQuartzJob implements Job {
    private String someParam;
    private int someParam2;

    public void setSomeParam(String someParam) {
        this.someParam = someParam;
    }

    public void setSomeParam2(int someParam2) {
        this.someParam2 = someParam2;
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        System.out.println("My job is running with " + someParam + ' '
                + someParam2);

    }

}

PersistableCronTriggerFactoryBean

package com.practise.quartz.jdbc;

import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailAwareTrigger;


    public class PersistableCronTriggerFactoryBean extends CronTriggerFactoryBean {

        @Override
        public void afterPropertiesSet() {
            super.afterPropertiesSet();

            //Remove the JobDetail element
            getJobDataMap().remove(JobDetailAwareTrigger.JOB_DETAIL_KEY);
        }
    }

AutowiringSpringBeanJobFactory

    public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
        implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    public Object createJobInstance(final TriggerFiredBundle bundle)
            throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job); // the magic is done here
        return job;
    }

}

spring-quartz-jdbc.xml

     <?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:task="http://www.springframework.org/schema/task"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="com.practise.quartz"></context:component-scan>


    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        id="dataSource">
        <property value="com.mysql.jdbc.Driver" name="driverClassName" />
        <property value="jdbc:mysql://localhost:3306/test" name="url" />
        <property value="root" name="username" />
        <property value="root" name="password" />
    </bean>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource" />

    </bean>

    <bean id="myJob"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.practise.quartz.jdbc.SimpleQuartzJob" />
        <property name="jobDataAsMap">
            <map>
                <entry key="someParam" value="some value" />
                <entry key="someParam2" value="1" />
            </map>
        </property>
        <property name="durability" value="true" />
    </bean>

    <bean id="quartzTriggers"
        class="com.practise.quartz.jdbc.PersistableCronTriggerFactoryBean">
        <!-- Reference to the job bean that will be triggered: -->
        <property name="jobDetail" ref="myJob" />
        <property name="cronExpression" value="0/5 * * * * ?" />
        <property name="misfireInstruction"
            value="#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_DO_NOTHING}" />
    </bean>

    <bean id="quartzJobFactory" class="com.practise.quartz.jdbc.AutowiringSpringBeanJobFactory">
        <property name="ignoredUnknownProperties" value="applicationContext" />
    </bean>

    <bean id="quartzScheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

        <property name="configLocation" value="classpath:quartz.properties" />
        <property name="dataSource" ref="dataSource" />
        <property name="transactionManager" ref="transactionManager" />

        <property name="schedulerName" value="quartzScheduler" />
        <property name="overwriteExistingJobs" value="true" />

        <property name="autoStartup" value="true" />
        <property name="applicationContextSchedulerContextKey" value="applicationContext" />

        <property name="jobFactory" ref="quartzJobFactory" />

        <!-- NOTE: Must add both the jobDetail and trigger to the scheduler! -->
        <property name="jobDetails">
            <list>
                <ref bean="myJob" />
            </list>
        </property>
        <property name="triggers">
            <list>
                <ref bean="quartzTriggers" />
            </list>
        </property>
    </bean>

</beans>

Test Method

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
public static void main(String[] args) {
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-quartz-jdbc.xml");

}
}

quartz.properties

org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true

# Change this to match your DB vendor
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Needed to manage cluster instances
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=SimpleQuazrtzJob  

org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

Console Logger

19:10:43,349  INFO main support.ClassPathXmlApplicationContext:513 - Refreshing 
19:10:43,572 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/beans/spring-beans-3.0.xsd] in classpath: org/springframework/beans/factory/xml/spring-beans-3.0.xsd
19:10:43,686 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/context/spring-context.xsd] in classpath: org/springframework/context/config/spring-context-4.0.xsd
19:10:43,704 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/tool/spring-tool-4.0.xsd] in classpath: org/springframework/beans/factory/xml/spring-tool-4.0.xsd
19:10:43,737 DEBUG main xml.DefaultBeanDefinitionDocumentReader:108 - Loading bean definitions
19:10:43,761 DEBUG main xml.DefaultNamespaceHandlerResolver:157 - Loaded NamespaceHandler mappings: {http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
19:10:43,947 DEBUG main xml.BeanDefinitionParserDelegate:465 - No XML 'id' specified - using 'exampleJob' as bean name and [] as aliases
19:10:43,954 DEBUG main xml.XmlBeanDefinitionReader:223 - Loaded 11 bean definitions from location pattern [spring-quartz-jdbc.xml]
19:10:44,011 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,011 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,043 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' to allow for resolving potential circular references
19:10:44,048 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,125 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,126 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,129 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' to allow for resolving potential circular references
19:10:44,130 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,130 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,131 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,132 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' to allow for resolving potential circular references
19:10:44,133 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,133 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,134 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,143 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' to allow for resolving potential circular references
19:10:44,144 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,144 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,145 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,145 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor' to allow for resolving potential circular references
19:10:44,146 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,146 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,147 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,147 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor' to allow for resolving potential circular references
19:10:44,148 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,163 DEBUG main support.DefaultListableBeanFactory:672 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@468a9e1a: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,simpleScheduler,dataSource,transactionManager,exampleJob,cronTrigger,quartzJobFactory,quartzScheduler,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; root of factory hierarchy
19:10:44,164 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,164 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,165 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,165 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,166 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'simpleScheduler'
19:10:44,166 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'simpleScheduler'
19:10:44,179 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'simpleScheduler' to allow for resolving potential circular references
19:10:44,203 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'simpleScheduler'
19:10:44,204 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'dataSource'
19:10:44,204 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'dataSource'
19:10:44,208 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'dataSource' to allow for resolving potential circular references
19:10:44,262  INFO main datasource.DriverManagerDataSource:133 - Loaded JDBC driver: com.mysql.jdbc.Driver
19:10:44,263 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'dataSource'
19:10:44,264 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'transactionManager'
19:10:44,264 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'transactionManager'
19:10:44,284 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'transactionManager' to allow for resolving potential circular references
19:10:44,294 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'dataSource'
19:10:44,299 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'transactionManager'
19:10:44,300 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'transactionManager'
19:10:44,301 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'exampleJob'
19:10:44,301 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'exampleJob'
19:10:44,313 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'exampleJob' to allow for resolving potential circular references
19:10:44,361 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'exampleJob'
19:10:44,387 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'exampleJob'
19:10:44,388 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'cronTrigger'
19:10:44,389 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'cronTrigger'
19:10:44,395 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'cronTrigger' to allow for resolving potential circular references
19:10:44,408 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'exampleJob'
19:10:44,410 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'cronTrigger'
19:10:44,460 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'cronTrigger'
19:10:44,461 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'quartzJobFactory'
19:10:44,461 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'quartzJobFactory'
19:10:44,466 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'quartzJobFactory' to allow for resolving potential circular references
19:10:44,473 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'quartzJobFactory'
19:10:44,474 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'quartzScheduler'
19:10:44,474 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'quartzScheduler'
19:10:44,490 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'quartzScheduler' to allow for resolving potential circular references
19:10:44,507 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'dataSource'
19:10:44,508 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'transactionManager'
19:10:44,510 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'quartzJobFactory'
19:10:44,511 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'cronTrigger'
19:10:44,512 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'quartzScheduler'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
19:10:44,532  INFO main quartz.SchedulerFactoryBean:553 - Loading Quartz config from [class path resource [quartz.properties]]
19:10:45,020 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'quartzScheduler'
19:10:45,021 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:45,021 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:45,023 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'quartzScheduler'
19:10:45,024 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'lifecycleProcessor'
19:10:45,026  INFO main support.DefaultLifecycleProcessor:341 - Starting beans in phase 2147483647
19:10:45,026  INFO main quartz.SchedulerFactoryBean:649 - Starting Quartz Scheduler now

Database data

qrtz_scheduler_state table-> qrtz_scheduler_state

qrtz_triggers table

在此处输入图片说明

qrtz_cron_triggers table

在此处输入图片说明

qrtz_job_details table

在此处输入图片说明

org.quartz.jobStore.useProperties=false

Standalone Quartz does not have any problem with this: just use 'org.quartz.jobStore.useProperties=true' in the 'quartz.properties' file. It tells Quartz to store the job parameters as is, not via Java serialization mechanism.

The problem is in the Spring + Quartz combination. Simply changing the above property will cause Quartz to fail with an error. Spring's *TriggerFactoryBeans silently store their jobs inside their triggers. Since job definitions are complex objects, they have to be stored using Java serialization mechanism, which contradicts the 'useProperties=true' setting.

http://codrspace.com/Khovansa/spring-quartz-with-a-database/

Be careful with cleaning the job details in PersistableCronTriggerFactoryBean . The parent class creates CronTriger in it's own afterPropertiesSet method and fully fills it. By cleaning you remove all info about the job that the trigger must run.

Try to run your app without custom CronTriggerFactory .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM