2006-12-13

疑问:Spring配置Quartz例子出错,请看下.谢谢

关键字: Spring Quartz
研究了一天,在官方论坛也查询了很多,就是锁定不了原因。请各位朋友帮忙看看
spring的配置如下:
    <bean id="emailJobBean" class="org.springframework.scheduling.quartz.JobDetailBean">
    	<property name="jobClass" value="EmailJobBean"/>
    </bean>
	<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
	    <property name="jobDetail" ref="emailJobBean" />
	    <property name="startDelay" value="2000" />
	    <property name="repeatInterval" value="60000" />
	</bean>
	<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
           <list>
           		<ref bean="simpleTrigger"/>
            </list>
        </property>
    </bean>  

其中被调度的bean
public class EmailJobBean extends QuartzJobBean {

	protected void executeInternal(JobExecutionContext arg0)
			throws JobExecutionException {
		System.out.println("Quartz !!!");
	}

}


启动后就保错
14:29:38,11882 ERROR  [org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:205)] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in ServletContext resource [/WEB-INF/classes/spring-quartz.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view does not exist

不知道有没有朋友遇到过类似问题?请大家指点
环境我用的是resin2.1.16,jdk1.4.2,spring2.0.1,quartz1.6.0
评论
eyejava 2007-03-08
dwangel 写道
另外可能是自动装配惹得祸,存在dataSource这个bean就自动用数据库的状态维持了。

dwangel 写道
foxty 写道
因为这个时候你的quartz是jobstore用的HDBCJobStore模式,此时会从数据库查询任务。

你如果只是测试的话,可以在你的classpath下加一个文件quartz.properties,并且加上一句org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore 。就会采取内存存储的模式了。

或者可以直接在spring配置中做:

<bean name="quartzScheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.class">
org.quartz.simpl.RAMJobStore
</prop>
</props>
</property>
</bean>

autowire真是一个万恶的家伙, 这个问题整了我一个下午,怒了.
设置org.quartz.jobStore.class为org.quartz.simpl.RAMJobStore也是没有用的.
因为
if (this.dataSource != null) {
				mergedProps.put(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
			}

SchedulerFactoryBean的setDataSource(DataSource)方法javadoc说:
Set the default DataSource to be used by the Scheduler. If set, this will override corresponding settings in Quartz properties.

Note: If this is set, the Quartz settings should not define a job store "dataSource" to avoid meaningless double configuration.

A Spring-specific subclass of Quartz' JobStoreCMT will be used. It is therefore strongly recommended to perform all operations on the Scheduler within Spring-managed (or plain JTA) transactions. Else, database locking will not properly work and might even break (e.g. if trying to obtain a lock on Oracle without a transaction).

Supports both transactional and non-transactional DataSource access. With a non-XA DataSource and local Spring transactions, a single DataSource argument is sufficient. In case of an XA DataSource and global JTA transactions, SchedulerFactoryBean's "nonTransactionalDataSource" property should be set, passing in a non-XA DataSource that will not participate in global transactions.

See Also:
setNonTransactionalDataSource
setQuartzProperties
setTransactionManager
LocalDataSourceJobStore
dwangel 2006-12-18
foxty 写道
因为这个时候你的quartz是jobstore用的HDBCJobStore模式,此时会从数据库查询任务。

你如果只是测试的话,可以在你的classpath下加一个文件quartz.properties,并且加上一句org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore 。就会采取内存存储的模式了。

或者可以直接在spring配置中做:

<bean name="quartzScheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.class">
org.quartz.simpl.RAMJobStore
</prop>
</props>
</property>
</bean>
dwangel 2006-12-18
按照错误信息显示,你使用的quartz应该是使用数据进行job的状态的维护的,但是在数据库中没有找到相应的table,从而无法正常建立scheduler 。

如果你的不需要错误重启功能,改成用内存维护就好。

另外可能是自动装配惹得祸,存在dataSource这个bean就自动用数据库的状态维持了。
foxty 2006-12-18
因为这个时候你的quartz是jobstore用的HDBCJobStore模式,此时会从数据库查询任务。

你如果只是测试的话,可以在你的classpath下加一个文件quartz.properties,并且加上一句org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore 。就会采取内存存储的模式了。
抛出异常的爱 2006-12-18
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--起动Bean-->
 <bean id="z" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
 	<property name="triggers">
 		<list>
 	
			<ref bean="cronReportTrigger"/>
 		</list>
 	</property>
 </bean> 
<!--实际的工作Bean-->
  <bean id="courseService" class="com.spring.helloworld.CourseService"></bean>
<!--jobBean用于设定启动时运用的Bean与方法-->
 <bean id="scheduledReportJobDetail"  
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
	 <property name="targetObject">
	 	<ref  bean="courseService"/>	
	 </property>
	 <property name="targetMethod">
		 <value>sendCourseEnrollmentReport</value>
	 </property>
 </bean>
<!--定时器设定起动频率&启动时间我设的是每5秒起动一次 (0 0 0 4 * * ?每日四点起动....)-->
 <bean id="cronReportTrigger" 
class="org.springframework.scheduling.quartz.CronTriggerBean">
 <property  name="jobDetail"><ref bean="scheduledReportJobDetail"/>
 </property>
 <property name="cronExpression"><value>10,15,20,25,30,35,40,45,50,55 * * * * ?</value>  
</property>
 </bean>
 	
</beans>

看了你的问题周日自己试着作了一次....

引用
14:29:38,11882 ERROR [org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:205)] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in ServletContext resource [/WEB-INF/classes/spring-quartz.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view does not exist

从没出过这种错.....
看来好像是你又以什么方式去调用数据库之后产生的问题
PS:你的EmailJobBean生明方式不对应该以小写开头,并用Bean标签声明...
抛出异常的爱 2006-12-14
init method failed?是否是你的Quartz实现的接口不对?
jobDataAsMap这个接口没看到配?
有没有关系?
moogle 2006-12-14
现在就是我的hibernate和quartz的配置不能并存 ,
这2者之间不会有啥不兼容吧。。。
moogle 2006-12-13
ddandyy 写道
很奇怪
<bean id="emailJobBean" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="EmailJobBean"/>
</bean>

你没定义 id=EmailJobBean 为什么这句不报错呢


赫赫 ,这个地方就是那个jobClass的值 就是一个类的完整名称,
我这个类没有包名,所以直接就是这么写的。
moogle 2006-12-13

binker 写道:

可疑之处: 1你的EmailJobBean有包前缀么? 若有那应该定义成 <property name="jobClass" value="com.yourpackagename.EmailJobBean"/>  

  [code]<bean id="emailJobBean" class="org.springframework.scheduling.quartz.JobDetailBean">  

  •     <property name="jobClass" value="EmailJobBean"/>  
  •    bean>  
  • [code]

    启动后就保错

    代码
    1. 14:29:38,11882 ERROR  [org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:205)] Context initialization failed   
    2. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in ServletContext resource [/WEB-INF/classes/spring-quartz.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view does not exist   

     

    可疑之处2:你的spring-quartz.xml 文件配置,注意到在错误堆栈的最后一行提示jdbcstore lock exception, table or view does not exist.是否其中配置了数据源信息.你可以尝试把其他所有的配置都注释掉,只保留quartz job bean的定义.然后再调试.

  • 谢谢先

    1.我只是做个测试,本身就没有加包。 如果在配置文件写错这些,eclipse会直接提示类不存在的,强行跑也会ClassNotFound

    2.我将hibernate配置的文件去掉。 Quartz可正常跑,去掉quartz,hibernate可以正常加载应用
      加在一起后就还是出现同样的错误。

    下面补spring-hibernate.xml 配置
    ----------------------------------------------------------------------

    1. <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
    2.     <property name="jndiName" value="${jdbc.jndiName}" />  
    3. bean>  
    4.   
    5. <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" autowire="byName"/>  
    6. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
    7.     <property name="dataSource" ref="dataSource" />  
    8.     <property name="mappingDirectoryLocations">  
    9.         <list>  
    10.         <value>classpath:org/moo/pojo/value>  
    11.         list>  
    12.     property>  
    13.     <property name="hibernateProperties">  
    14.         <props>  
    15.             <prop key="hibernate.dialect">${hibernate.dialect}prop>  
    16.             <prop key="hibernate.show_sql">${hibernate.show_sql}prop>  
    17.         props>  
    18.     property>  
    19. bean>  
    20.  //下面都是类似的dao,service比较多就不一一列出来了   
    21.  <bean id="codeService" class="org.moo.service.CodeService" autowire="byName"/>  
    22.  <bean id="codeDao" class="org.moo.dao.CodeDao" autowire="byName"/>  


    另我看日志输入在出现错误前有:

    1. 15:43:50,23182 INFO   [org.quartz.core.QuartzScheduler.(QuartzScheduler.java:209)] Quartz Scheduler v.null.null.null created.   
    2. 15:43:50,23241 INFO   [org.quartz.impl.jdbcjobstore.JobStoreSupport.initialize(JobStoreSupport.java:542)] Using db table-based data access locking (synchronization).   
    3. 15:43:50,23390 DEBUG  [org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:106)] Lock 'TRIGGER_ACCESS' is desired by: main   
    4. 15:43:50,24023 DEBUG  [org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:88)] Lock 'TRIGGER_ACCESS' is being obtained: main   
    5. 15:43:51,24291 DEBUG  [org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:107)] Lock 'TRIGGER_ACCESS' was not obtained by: main   
    6. 15:43:51,24332 DEBUG  [org.quartz.utils.ExceptionHelper.supportsNestedThrowable(ExceptionHelper.java:97)] Detected JDK support for nested exceptions.   
    7. 15:43:51,24427 INFO   [org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:272)] Destroying singletons in {org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans   
    8. 15:43:51,24438 INFO   [org.springframework.orm.hibernate3.AbstractSessionFactoryBean.destroy(AbstractSessionFactoryBean.java:185)] Closing Hibernate SessionFactory  


    然后才出现了最先提到的错误

    ddandyy 2006-12-13
    很奇怪
    <bean id="emailJobBean" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="EmailJobBean"/>
    </bean>

    你没定义 id=EmailJobBean 为什么这句不报错呢
    moogle 2006-12-13
    ...
    我只给出了和quartz相关的,其他的就还有一个hibernate的配置
    然后就没有了。
    去掉quartz的都很正常的跑。这个quartz跑得和hibernate一点关系都没有

    总共分了3个配置
    spring.xml
    ----------------------
    <beans default-autowire="byName">
    	<!-- 加载全局配置文件 -->
    	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="locations">
    			<list>
    				<value>classpath:/mail.properties</value>
    				<value>classpath:/jdbc.properties</value>
    				<value>classpath:/hibernate.properties</value>
    			</list>
    		</property>
    	</bean>
    </beans>
    

    spring-hibernate.xml就是配置了数据源和dao,service
    spring-quartz.xml就是一楼的那些内容
    binker 2006-12-13

    可疑之处: 1你的EmailJobBean有包前缀么? 若有那应该定义成 <property name="jobClass" value="com.yourpackagename.EmailJobBean"/>  

      [code]<bean id="emailJobBean" class="org.springframework.scheduling.quartz.JobDetailBean">  

  •     <property name="jobClass" value="EmailJobBean"/>  
  •    </bean>  
  • [code]
  • 启动后就保错

    代码
    1. 14:29:38,11882 ERROR  [org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:205)] Context initialization failed   
    2. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in ServletContext resource [/WEB-INF/classes/spring-quartz.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ORA-00942: table or view does not exist   

     

    可疑之处2:你的spring-quartz.xml 文件配置,注意到在错误堆栈的最后一行提示jdbcstore lock exception, table or view does not exist.是否其中配置了数据源信息.你可以尝试把其他所有的配置都注释掉,只保留quartz job bean的定义.然后再调试.

    ddandyy 2006-12-13
    那就是配置文件有问题

    你给出来的不全吧
    moogle 2006-12-13
    引用
    public class EmailJobBean implements StatefulJob


    测试后,错误依旧。
    @-@.

    PS:感谢回帖。
    ddandyy 2006-12-13
    public class EmailJobBean implements StatefulJob

    你试试
    moogle
    搜索本博客
    我的相册
    E1f9db4d-86b3-46d5-8407-8009bde36b18-thumb
    MSN Cartoon 生成肖像图 表情系列 13
    共 14 张
    最近加入圈子
    存档
    最新评论
    评论排行榜