jBPM的Scheduler模块和Spring集成失败
我的Web系统中使用了jBPM,并使用Spring来管理bean,并使用Spring+JTOM组合来管理来自多个数据库的事务(有Oracle9i,Microsoft SQL Server 2000)。但是没有使用jBPM的Scheduler。系统运行很好。
最近由于业务需要,我在jBPM中添加了timer。这样,就需要配置一个Scheduler了。而我的麻烦也从此开始。
我一开始使用jBPM提供的那个SchedulerServlet,可是发现这个Servlet会去自动加载jBPM的默认配置,也就是在default.jbpm.ctf.xml中配置的属性,特别是数据库的配置。这样,我的Spring就无法管理它的事务了。
我查看了它的源代码,发现其代码如下(省略了不相干代码):
public class SchedulerServlet extends HttpServlet { private static final long serialVersionUID = 1L; Scheduler scheduler = null; public void init() throws ServletException { // create a new scheduler scheduler = new Scheduler(); // start the scheduler scheduler.start(); } ...}public class Scheduler { SchedulerThread schedulerThread = null; ... public void start() { log.debug("starting the scheduler"); schedulerThread = new SchedulerThread(); schedulerThread.setInterval(interval); schedulerThread.addListener(new HistoryListener()); schedulerThread.start(); } ...}public class SchedulerThread extends Thread { JbpmConfiguration jbpmConfiguration = null; String jbpmContextName = null; ... public SchedulerThread() { this(JbpmConfiguration.getInstance(), JbpmContext.DEFAULT_JBPM_CONTEXT_NAME); } ...}
package org.jbpm.scheduler.impl;...public class SpringAwareScheduler extends Scheduler { private static final Log log = LogFactory.getLog(SpringAwareScheduler.class); protected JbpmConfiguration jbpmConfiguration; public SpringAwareScheduler() { this(null); } public SpringAwareScheduler(JbpmConfiguration jbpmConfiguration) { super(); this.jbpmConfiguration = jbpmConfiguration; } /** * @param jbpmConfiguration the jbpmConfiguration to set */ public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) { this.jbpmConfiguration = jbpmConfiguration; } public void start() { log.debug("starting the scheduler"); schedulerThread = new SchedulerThread(this.jbpmConfiguration); schedulerThread.setInterval(interval); schedulerThread.addListener(new HistoryListener()); schedulerThread.start(); }}
public class SpringAwareJbpmSchedulerListener implements ServletContextListener { private Scheduler scheduler = null; @Override public void contextDestroyed(ServletContextEvent sce) { scheduler.stop(); } @Override public void contextInitialized(ServletContextEvent sce) { // create a new scheduler String beanName = sce.getServletContext().getInitParameter("jbpmConfigurationBeanName"); if (StringUtils.isBlank(beanName)) { beanName = "jbpmConfiguration"; } WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()); JbpmConfiguration jbpmConfiguration = (JbpmConfiguration) wac.getBean(beanName); scheduler = new SpringAwareScheduler(jbpmConfiguration); JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME); SessionFactory sessionFactory = jbpmContext.getSessionFactory(); assert sessionFactory != null; // initialize it with the servlet init parameters int interval = 5000; if (!StringUtils.isBlank(sce.getServletContext().getInitParameter("interval"))) { interval = Integer.parseInt(sce.getServletContext().getInitParameter("interval")); } scheduler.setInterval(interval); int historyMaxSize = 50; if (!StringUtils.isBlank(sce.getServletContext().getInitParameter("historyMaxSize"))) { historyMaxSize = Integer.parseInt(sce.getServletContext().getInitParameter("historyMaxSize")); } scheduler.setHistoryMaxSize(historyMaxSize); // put the scheduler in the web app context sce.getServletContext().setAttribute("scheduler", scheduler); // start the scheduler scheduler.start(); }}
10:19:32,939 FATAL [org.hibernate.connection.DatasourceConnectionProvider] - Could not find datasource: java:/DefaultDSjavax.naming.NameNotFoundExceptionat org.objectweb.carol.jndi.enc.java.CompNamingContext.lookupCtx(CompNamingContext.java:689)at org.objectweb.carol.jndi.enc.java.CompNamingContext.lookup(CompNamingContext.java:179)at org.objectweb.carol.jndi.enc.java.JavaURLContext.lookup(JavaURLContext.java:138)at javax.naming.InitialContext.lookup(InitialContext.java:392)at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:56)at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:414)at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:91)at org.jbpm.persistence.db.DbPersistenceService.getSessionFactory(DbPersistenceService.java:76)at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:80)at org.jbpm.persistence.db.DbPersistenceService.getSchedulerSession(DbPersistenceService.java:261)at org.jbpm.JbpmContext.getSchedulerSession(JbpmContext.java:531)at org.jbpm.scheduler.impl.SchedulerThread.executeTimers(SchedulerThread.java:104)at org.jbpm.scheduler.impl.SchedulerThread.run(SchedulerThread.java:71)