`
Frederick
  • 浏览: 117793 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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);
  }
  ...
}


我查找了相关资源,发现没有现成的和Spring集成的工具。(jBPM的核心引擎已经有spring-module提供了集成工具)。我想,那我自己覆盖这个SchedulerServlet,让这个SchedulerThread使用Spring管理下的JbpmConfiguration实例,那不就可以达到目的了吗?于是动手。

可是这时候才发现,这个jBPM提供的Scheduler对象,根本就没有可以让我能够向SchedulerThread注射入JbpmConfiguration的入口。而且这个类是default的可见范围,连继承扩展都做不到。迫于无奈,我在Scheduler的相同package下,建了一个子类,来提供注入Spring管理的JbpmConfiguration实例的能力,然后自己写了一个ServletContextListener来加载这个监听线程。
代码如下:
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();
    }
}

这里是用来取代SchedulerServlet的ServletContextListener:
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();
    }
}


好了,以为现在在web.xml中配置好了以后,总该可以了吧?可是不然。问题又来了。发现系统在启动的过程中,根本没有使用在JbpmConfiguration实例中配置的SessionFactory,而是继续使用根据default.jbpm.cfg.xml中的配置生成的那个SessionFactory实例。
我单步跟踪了一下代码,发现之所以会去加载根据default.jbpm.cfg.xml中的配置生成的那个SessionFactory实例,原因是在DbPersistenceService在获取SessionFactory实例的时候,发现为空,所以就按照默认配置去创建一个新的SessionFactory实例。异常信息如下:
10:19:32,939 FATAL [org.hibernate.connection.DatasourceConnectionProvider] - Could not find datasource: java:/DefaultDS
javax.naming.NameNotFoundException
	at 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)

可是,明明DbPersistenceService的实例是根据JbpmContext创建的,而JbpmContext又是根据JbpmConfiguration实例创建的。也就是说,DbPersistenceService使用的SessionFactory的实例应该是来自JbpmConfiguration的实例中的那个。为什么实际上却为空呢?

现在我晕掉了。到底错误在那里呢?
分享到:
评论
2 楼 ossd_小羊 2008-11-04  
是jbpm3.2.3版本吗?
1 楼 gabriel80 2008-05-14  
提示个方法。。用JobExecutorServlet方法来代替你的SchedulerServlet 。
由于我还没有完全弄明白。。只能提供你一个方向。。
抱歉。。。。。
关注中。。。。。。。。

相关推荐

    jbpm4 集成 spring 的试用代码

    jbpm4是一款强大的业务流程...总的来说,jbpm4与Spring的集成可以提高流程管理的灵活性和可扩展性,使得开发者能够更好地管理和控制业务流程。在实际开发中,应充分理解并掌握上述知识点,以实现高效、稳定的流程应用。

    jbpm5.4 spring mvc 集成

    jbpm5.4与Spring MVC的集成是企业级应用开发中的常见组合,它结合了jbpm(业务流程管理)的强大功能和Spring MVC的灵活控制层架构。以下将详细阐述这一集成涉及的关键知识点: 1. **jbpm5.4**:jbpm是一个开源的...

    jbpm4.3与spring整合

    - `jbpm-4.3/install/src/cfg/jbpm/spring.jbpm.cfg.xml`:JBPM与Spring集成的关键配置文件。 #### 三、配置文件调整 接下来,我们将对这些配置文件进行必要的修改。 1. **调整`hibernate.cfg.xml`**:在`...

    jbpm与spring集成

    10. **测试与调试**:在Spring测试框架的支持下,可以编写单元测试和集成测试,验证jbpm流程的正确性和性能。 通过以上知识点的学习和实践,开发者能够熟练掌握jbpm与Spring的集成,构建出强大而灵活的业务流程管理...

    Spring与JBPM4的集成.docx

    Spring框架和JBPM4的集成是指将Spring框架与JBPM4业务流程管理系统集成,以便更好地管理业务流程和工作流程。这种集成可以提供更加灵活和高效的业务流程管理解决方案。 知识点1:为什么需要Spring Integration? ...

    spring与jbpm的集成包(符集成方法)

    Spring 和 JBPM 集成是一项关键的技术任务,它允许开发者在基于 Spring 的应用程序中无缝地集成业务流程管理(BPM)功能。JBPM 是一个开源的 BPM 解决方案,提供工作流服务、流程建模、执行和监控等功能。下面我们将...

    jbpm4.4 ibatis-spring 整合

    jbpm4.4 ibatis-spring 整合

    JBPM与Spring集成开发指南

    将JBPM与Spring集成,可以充分利用Spring的IoC(Inversion of Control)和AOP(Aspect Oriented Programming)特性,以及其丰富的生态系统,来管理和控制工作流的生命周期。 在集成JBPM与Spring时,首先需要理解...

    JBPM与Spring集成开发指南.docx

    - 事务一致性:在Spring和JBPM中正确配置事务边界,确保业务流程的原子性。 - 性能优化:合理设计和配置工作流,避免性能瓶颈。 - 扩展性和可维护性:设计可插拔的工作流组件,便于后期维护和升级。 总之,JBPM...

    提前试用spring 集成 jbpm4

    总的来说,"提前试用spring 集成 jbpm4"意味着你需要理解Spring框架和jbpm4 BPM平台的工作原理,学习如何在Spring环境中配置和使用jbpm4,以及如何设计和部署符合业务需求的工作流程。这个过程涵盖了数据库配置、...

    jbpm 项目实践 1.2 (集成appfuse spring modules)

    集成jbpm、appfuse和Spring Modules的主要目的是利用它们各自的优势,实现业务流程的自动化管理和灵活的依赖注入,以及提供良好的安全性和架构支持。以下是一些关键知识点: 1. **jbpm集成**:jbpm的流程定义使用...

    jBPM4与Spring整合的2种方式

    1. **引入Spring-JBPM4依赖**:Spring社区提供了Spring-JBPM4模块,可以直接集成到Spring应用中。添加相应的Maven或Gradle依赖。 2. **配置jbpmContext**:创建一个jbpmContext的bean,它会自动配置jBPM4所需的服务...

    JBPM5 整合Spring3经典案例

    Spring3还包含了数据访问、事务管理、Web应用和集成测试等多种模块,使得开发者可以构建松耦合、模块化的应用系统。 ### 3. JBPM5与Spring3整合 - **依赖注入**:通过Spring的DI,可以将JBPM的相关组件(如流程...

    jbpm+spring配置

    1. **引入依赖**:首先,要在Spring应用中使用jbpm,你需要在项目中引入jbpm的相关库,包括jbpm的jar包和Spring对jbpm的支持库。这通常通过Maven或Gradle的依赖管理来实现。 2. **配置jbpm数据源**:jbpm需要一个...

    JBPM与Spring集成开发指导书.doc

    【JBPM与Spring集成开发】\n\nJBPM(Java Business Process Management)是一个开源的工作流管理系统,它允许开发者设计、执行、监控和优化业务流程。Spring框架则是一个广泛应用的Java企业级应用开发框架,提供了...

    Spring与JBoss JBPM工作流集成开发指南

    本指南旨在介绍如何将JBoss JBPM与Spring框架集成,以便更好地管理和自动化业务流程。 #### 二、工作流管理系统的概念 **工作流(Workflow)**: 工作流是指业务过程中的文档、信息或任务按照预定义的规则在参与者...

    JBPM使用实例,sql spring

    通过上述文件,你可以学习到如何将JBPM、Spring和SQL结合,实现一个完整的业务流程管理系统。首先,你需要了解Spring环境下的配置,包括Spring与JBPM的集成方式。然后,你需要熟悉JBPM的流程定义语言和工具,创建...

    JBPM与Spring集成开发指导书.docx

    在集成JBPM和Spring时,开发者可以利用Spring的强大依赖注入和AOP(面向切面编程)能力,来管理和控制工作流的生命周期。工作流在企业中扮演着至关重要的角色,它定义了业务过程的顺序,确保文档、信息或任务按照...

Global site tag (gtag.js) - Google Analytics