2

我正在尝试将 Spring 中的数据源配置集成到 Quartz 调度程序中。虽然我从论坛和邮件列表中收集了一些关于如何做到这一点的信息,但我仍然无法构建整个部分。

我在 Spring 中配置了数据源,如下所示:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/projectA"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="cache" value="true"/>
    <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

Quartz-Spring 配置如下:

<jee:jndi-lookup id="quartzDataSource" 
    lookup-on-startup="false" 
    proxy-interface="javax.sql.DataSource" 
    cache="true" 
    jndi-name="java:jdbc/projectA"/>

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

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

这不是正确的配置,因为我收到以下错误:

[ERROR   ] SRVE0283E: Exception caught while initializing context: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' defined in class path resource [job-authentication-spring.xml]: Invocation of init method failed; nested exception is org.springframework.jndi.JndiLookupFailureException: JndiObjectTargetSource failed to obtain new target object; nested exception is javax.naming.InvalidNameException: java:jdbc/projectA
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:518)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:1975)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:748)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:5694)
    at com.ibm.ws.webcontainer.osgi.webapp.WebGroup.addWebApplication(WebGroup.java:84)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.addWebApplication(DynamicVirtualHost.java:150)
    at com.ibm.ws.webcontainer.WebContainer.addWebApp(WebContainer.java:571)
    at com.ibm.ws.webcontainer.WebContainer.addWebApplication(WebContainer.java:521)
    at com.ibm.ws.webcontainer.osgi.WebContainer.addWebContainerApplication(WebContainer.java:649)
    at com.ibm.ws.app.manager.war.internal.WARApplicationHandler.install(WARApplicationHandler.java:153)
    at com.ibm.ws.app.manager.internal.statemachine.StartAction.execute(StartAction.java:145)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:358)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:248)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.processChange(ApplicationStateMachine.java:138)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.changed(ApplicationStateMachine.java:120)
    at com.ibm.ws.app.manager.internal.statemachine.LocateHandlerAction.arrived(LocateHandlerAction.java:91)
    at com.ibm.ws.app.manager.internal.lifecycle.ReferenceMapHolder.addListener(ReferenceMapHolder.java:191)
    at com.ibm.ws.app.manager.internal.statemachine.LocateHandlerAction.execute(LocateHandlerAction.java:65)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:358)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:248)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.processChange(ApplicationStateMachine.java:138)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.changed(ApplicationStateMachine.java:120)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$ResourceCallback.succesfulCompletion(ApplicationStateMachine.java:154)
    at com.ibm.ws.app.manager.internal.statemachine.ResolveFileAction.findFile(ResolveFileAction.java:95)
    at com.ibm.ws.app.manager.internal.statemachine.ResolveFileAction.initComplete(ResolveFileAction.java:135)
    at com.ibm.ws.kernel.filemonitor.internal.MonitorHolder.init(MonitorHolder.java:325)
    at com.ibm.ws.kernel.filemonitor.internal.CoreServiceImpl.setMonitor(CoreServiceImpl.java:211)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:227)
    at org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:38)
    at org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:595)
    at org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:476)
    at org.apache.felix.scr.impl.manager.DependencyManager.invokeBindMethod(DependencyManager.java:1067)
    at org.apache.felix.scr.impl.manager.DependencyManager.serviceAdded(DependencyManager.java:317)
    at org.apache.felix.scr.impl.manager.DependencyManager.serviceChanged(DependencyManager.java:171)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:950)
    at com.ibm.ws.app.manager.internal.lifecycle.ServiceReg.register(ServiceReg.java:89)
    at com.ibm.ws.app.manager.internal.statemachine.ResolveFileAction.execute(ResolveFileAction.java:110)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:358)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:248)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.processChange(ApplicationStateMachine.java:138)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine$StateChangeCallback.changed(ApplicationStateMachine.java:120)
    at com.ibm.ws.app.manager.internal.statemachine.StopAction$1.succesfulCompletion(StopAction.java:56)
    at com.ibm.ws.app.manager.internal.statemachine.StopAction$1.succesfulCompletion(StopAction.java:52)
    at com.ibm.ws.threading.internal.FutureMonitorImpl$FutureMonitorInfo.notifyListener(FutureMonitorImpl.java:49)
    at com.ibm.ws.threading.internal.FutureMonitorImpl.onCompletion(FutureMonitorImpl.java:93)
    at com.ibm.ws.app.manager.internal.statemachine.StopAction.execute(StopAction.java:52)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:358)
    at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachine.changeState(ApplicationStateMachine.java:248)
    at com.ibm.ws.app.manager.internal.monitor.ApplicationMonitor$EventType.executeEvent(ApplicationMonitor.java:314)
    at com.ibm.ws.app.manager.internal.monitor.ApplicationMonitor$ApplicationListeners.executeEvent(ApplicationMonitor.java:284)
    at com.ibm.ws.app.manager.internal.monitor.ApplicationMonitor$ApplicationListeners.access$600(ApplicationMonitor.java:183)
    at com.ibm.ws.app.manager.internal.monitor.ApplicationMonitor$ApplicationListeners$1.call(ApplicationMonitor.java:268)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.jndi.JndiLookupFailureException: JndiObjectTargetSource failed to obtain new target object; nested exception is javax.naming.InvalidNameException: java:jdbc/projectA
    at org.springframework.jndi.JndiObjectTargetSource.getTarget(JndiObjectTargetSource.java:139)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:182)
    at $Proxy20.getConnection(Unknown Source)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:280)
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:320)
    at org.springframework.scheduling.quartz.LocalDataSourceJobStore.initialize(LocalDataSourceJobStore.java:139)
    at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:1318)
    at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1509)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.createScheduler(SchedulerFactoryBean.java:600)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:481)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1479)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1419)
    ... 87 more
Caused by: javax.naming.InvalidNameException: java:jdbc/projectA
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLName.<init>(JavaURLName.java:83)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLNameParser.parse(JavaURLNameParser.java:36)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLNameParser.parse(JavaURLNameParser.java:48)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext$NameUtil.<init>(JavaURLContext.java:458)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:299)
    at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:354)
    at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
    at org.springframework.jndi.JndiObjectTargetSource.getTarget(JndiObjectTargetSource.java:132)
    ... 100 more

我不确定这个 Spring 配置中还缺少什么,希望你们能分享一些关于这个问题的信息。

4

1 回答 1

5

我不确定为什么会发生这个问题,但这是我为了让它工作而做的:

首先,我扩展org.springframework.scheduling.quartz.SchedulerFactoryBean以创建自己的实现MySchedulerFactoryBean

然后将其连接到 spring 上下文 xml 中:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDS" />
    <property name="annotatedClasses">
        <list>
 ... your list of orm classes 
       </list>
</property>
</bean>


<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="myDS" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${database.driverClassName}" />
    <property name="initialSize" value="${database.initialSize}" />
    <property name="maxActive" value="${database.maxActive}" />
    <property name="maxIdle" value="${database.maxIdle}" />
    <property name="testOnBorrow" value="true"/>
    <property name="testWhileIdle" value="false"/>
    <property name="validationQuery" value="${database.validationQuery}" />
</bean>


<bean id="myQuartzSchedFactoryBean" class="com.scheduler.MySchedulerFactoryBean"
    lazy-init="true" scope="prototype">
    <!-- This datasource is initially passed as the default one, but later set internally in the code -->
    <property name="dataSource" ref="myDS" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="configLocation" value="classpath:META-INF/quartz.properties" />
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
    <property name="autoStartup" value="false" />
</bean>

然后,无论何时我想安排工作,我都会得到一个 MySchedulerFactoryBean 的实例并像这样使用它

MySchedulerFactoryBean quartzSchedulerFactoryBean = //get the bean from spring
Scheduler scheduler = quartzSchedulerFactoryBean.getScheduler();
scheduler.schedule(...)

这些是quartz.properties 条目:

org.quartz.scheduler.instanceName = MyScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 30
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

我正在使用 Quartz 2.1.2

于 2013-07-02T10:50:16.127 回答