Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: use jbpm31 module in test

  1. #1
    Join Date
    Apr 2006
    Location
    Saint-Petersburg, Russia
    Posts
    50

    Question use jbpm31 module in test

    Hello!
    May be somebody may help me. I'm using spring-jbpm31 module (build from last sources) for may BPM-based tool.

    For all process we have in my system we write unit-tests. All this unit-tests are inherited from one class - here is some part of code:

    Code:
    public class AbstractProcessTest extends TestCase {
    /// application context
    private ApplicationContext m_ac;
    	
    /// task management session
    TaskMgmtSession 	m_tms;
    	
    /// tested process definition
    ProcessDefinition	m_processDef;
    
    protected void setUp() throws Exception {
      m_ac = new FileSystemXmlApplicationContext("src/config.files/applicationContext.xml");
      assertNotNull(m_ac);
            
      JbpmConfiguration jbpmConfiguration = (JbpmConfiguration)m_ac.getBean("jbpmConfiguration");
      assertNotNull(jbpmConfiguration);
    
      JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
      assertNotNull(jbpmContext);
             
      m_tms = JbpmContext.getCurrentJbpmContext().getTaskMgmtSession();
      assertNotNull(m_tms);
    }
    
    protected void tearDown() throws Exception {
      m_processDef = null;
      m_tms = null;
      m_ac = null;
        	
      /// close jbpm context
      if (JbpmContext.getCurrentJbpmContext() != null) {
        JbpmContext.getCurrentJbpmContext().close();
      }
    }
    So, tis code creates application context from, creates jbpm configuration, gets the context from it and then in test case I load process definition into this context and use it.

    After making test I close context.

    Everything work fine.... only for one test - then I try to run two test on second setUp I've got an error:
    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jbpmConfiguration' defined in file [D:\work\processes\workspace\EmDevProcesses\src\config.files\applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    	at org.springmodules.workflow.jbpm31.JbpmFactoryLocator.addToMap(JbpmFactoryLocator.java:108)
    	at org.springmodules.workflow.jbpm31.JbpmFactoryLocator.setBeanFactory(JbpmFactoryLocator.java:76)
    	at org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean.setBeanFactory(LocalJbpmConfigurationFactoryBean.java:70)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:818)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:418)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:241)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:152)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:247)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:331)
    	at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:89)
    	at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:74)
    	at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:65)
    	at ru.emdev.EmDevProcesses.tests.AbstractProcessTest.setUp(AbstractProcessTest.java:42)
    	at ru.emdev.EmDevProcesses.tests.ToBuyProcessTestCase.setUp(ToBuyProcessTestCase.java:18)
    	at junit.framework.TestCase.runBare(TestCase.java:125)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    So, seems my jbpmConfiguration keep somethere (even if I created new application context) and I can not create new one

    But may be somebody know how it is possible to kill it?

    PS. Additionally here is my applicationContext.xml
    Code:
    <beans>
    	<!-- Database settings -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
            <property name="url" value="jdbc:hsqldb:mem:.;sql.enforce_strict_size=true"/>
            <property name="username" value="sa"/>
            <property name="password" value=""/>
        </bean>
        
        <!-- hibernate settings -->
        <bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <property name="mappingLocations">
            	<list>
                	<value>classpath*:/org/jbpm/**/*.hbm.xml</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
            
            <property name="schemaUpdate" value="true"/>
        </bean>
        
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref local="hibernateSessionFactory"/>
            </property>
        </bean>
    
    
    	<!-- JBPM Configuration -->    
        <bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
    		<property name="sessionFactory" ref="hibernateSessionFactory"/>
    		<property name="configuration" value="classpath:/ru/emdev/EmForge/jbpm.cfg.xml"/>
        </bean>
    </beans>
    Seems it is more then standard

    Does anybody have any suggestions?
    With best regards,
    Alexey Kakunin
    EmForge: Liferay based project hosting service

  2. #2
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    I think there is a problem with your test case. Since jbpm uses a lot of static references the integration code is forced to use static calls and variables. The JbpmFactoryLocator is used to discover the jbpmSessionFactory and place them in a static context to be used for the Action injection.
    Even though you are closing the jbpm context you are not closing the Spring application context.
    I recommend you take a look at the Spring test suite which will load your application context and cache it between your tests. Take a look at the test suite from jbpm integration for some examples.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  3. #3
    Join Date
    Apr 2006
    Location
    Saint-Petersburg, Russia
    Posts
    50

    Default Cannot find assigned tasks

    Costin, thank you very much for your advice. I looked into Spring Test Framework morfe detail and finally understand a little bit more how some Jbpm31 module tests work.

    So, I rewrote my basic class to use Spring Test-Framework and JbpmTemplate like this:

    Code:
    package ru.emdev.EmDevProcesses.tests;
    
    import java.util.List;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.jbpm.graph.def.Node;
    import org.jbpm.graph.exe.ProcessInstance;
    import org.jbpm.graph.exe.Token;
    import org.jbpm.taskmgmt.exe.TaskInstance;
    import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
    import org.springmodules.workflow.jbpm31.JbpmTemplate;
    
    import ru.emdev.ProcessManager.bean.ProcessDefBean;
    import ru.emdev.ProcessManager.bean.TaskBean;
    
    /** Basic class for Process Tests
     * 
     */
    public class AbstractProcessTest extends AbstractDependencyInjectionSpringContextTests {
    	private static Log log = LogFactory.getLog(AbstractProcessTest.class);
    	
    	/// template class to store jbpm template
    	/// setTemplate implemented in every test case to get 
    	/// the exactly template we are going to test
    	JbpmTemplate		m_template;
    	
    	protected String[] getConfigLocations() {
    		return new String[] {"ru/emdev/EmDevProcesses/tests/applicationContext.xml"};
    	}
    	
        /** Starts New Process
         * 
         * This function starts new process for m_processDef, 
         * assigns description and process owner
         * @param i_description - description for created process 
         * @param i_user - owner for created process
         * 
         * @return Start Task Instance for created Process
         */
        protected TaskInstance startProcess(String i_description,
        									String i_user) {
        	assertNotNull(i_description);
        	assertNotNull(i_user);
        	
        	log.info("Start new Process");
        	
        	ProcessInstance process = m_template.getProcessDefinition().createProcessInstance();
        	assertNotNull(process);
        	
    		//get start task
    		TaskInstance startTask = process.getTaskMgmtInstance().createStartTaskInstance();
    		assertNotNull(startTask);
    
    		// now, assign initial values to the task
    		startTask.setVariable(TaskBean.DESCRIPTION_VARIABLE, i_description);
    		startTask.setVariable(ProcessDefBean.OWNER_VARIABLE, i_user);
    
    		return startTask;
        }
        
        /** Ends the specified task and check next task assignment
         * 
         * @param i_prevTask - task to end
         * @param i_nextTaskOwner- owner of next assigned task
         * @param i_nextTaskName - name of the next task
         * 
         * @return next task
         */
        protected TaskInstance endTask(TaskInstance i_prevTask,
        							   String i_nextTaskOwner,
        							   String i_nextTaskName) {
        	assertNotNull(i_prevTask);
        	assertNotNull(i_nextTaskOwner);
        	assertNotNull(i_nextTaskName);
        	
        	log.info("Finish Task " + i_prevTask.getName());
    		// end task
        	i_prevTask.end();
    
    		// get current task
    		TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
    		
    		// check next node
    		checkNode(task.getToken(), i_nextTaskName);
    		
    		return task;
        }
        
        /** Ends the specified task by specified transition 
         * and check next task assignment
         * 
         * @param i_transitionName - transition to leave the node
         * @param i_prevTask - task to end
         * @param i_nextTaskOwner- owner of next assigned task
         * @param i_nextTaskName - name of the next task
         * 
         * @return next task
         */
        protected TaskInstance endTask(TaskInstance i_prevTask,
    			   					   String i_transitionName,
        							   String i_nextTaskOwner,
    			   					   String i_nextTaskName) {
        	assertNotNull(i_prevTask);
        	assertNotNull(i_transitionName);
        	assertNotNull(i_nextTaskOwner);
        	assertNotNull(i_nextTaskName);
        	
    		// end task
        	i_prevTask.end(i_transitionName);
    
    		// check next node
    		checkNode(i_prevTask.getToken(), i_nextTaskName);
    		
    		// get current task
    		TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
    		
    		return task;
        }
        /** check the node for specified token 
         * 
         * @param i_token token to check
         * @param i_nodeName - name of expected node
         */
        protected void checkNode(Token i_token, String i_nodeName) {
        	assertNotNull(i_token);
        	assertNotNull(i_nodeName);
        	
    		Node node = i_token.getNode();
    		assertNotNull(node);
    		
    		assertEquals(i_nodeName, node.getName());
        }
        
        /** Checks that specified user has only one task with specified name and returns this task
         * 
         * @param i_user - user to check
         * @param i_taskName - expected task name
         * 
         * @return expected task
         */
        protected TaskInstance getOneTask(String i_user, String i_taskName) {
        	assertNotNull(m_template);
        	assertNotNull(i_user);
        	assertNotNull(i_taskName);
        	
    		List tasks = m_template.findTaskInstances(i_user);
    		assertNotNull(tasks);
    		
    		assertEquals(i_user + " should have only 1 task",
    					 1,
    					 tasks.size());
    		
    		TaskInstance task = (TaskInstance)tasks.get(0);
    		assertNotNull(task);
    		
    		//check task instance name
    		assertEquals(i_taskName, task.getName());
        	
    		return task;
        }
        
        /** Checks that specified user has not active tasks assigned to him
         * 
         * @param i_user - user to check
         */
        protected void checkNoTasks(String i_user) {
        	assertNotNull(m_template);
        	assertNotNull(i_user);
        	
    		// user akakunin should have no tasks
    		List tasks = m_template.findTaskInstances(i_user);
    		assertEquals(i_user + " should have no task",
    				 0,
    				 tasks.size());
        }
    }
    In inherited test I just implement required setter to set tested template like:
    Code:
    class ToDoProcessTest extends AbstractProcessTest {
        setToDoTemplate(JbpmTemplate i_template) {
            m_template = i_template;
        }
    
        public void testProcess() {
            assertNotNull(m_template);
    		
            //get start task
            TaskInstance startTask = startProcess("Do something!", "somebody");
             
            TaskInstance nextTask = endTask(startTask, "somebody", "Assign ToDo");
    
            ......
    }
    Everything works quite well, I've got template, may start new process instance, set variable, finish start task, I can see that my assigner was called and next task was assigned to 'somebody'... but then I try to get active tasks for this 'somebody' via JbpmTemplate::findTaskInstance I've got nothing

    I looked into JbpmTemplate code and found that all of these methods are called in doInJbpm wrappers... but my process instance was created from process definition without any these wrappers - may be this is a problem?

    It really seems that my process instance lives in another JbpmContext/HibernateSession then code called in JbpmTemplate's doInJbpm wrapper - but if it so - how to change it?

    I feel that I'm near to setup my process testing properly according to Spring Framework, but still need to fix some problem. Does you have any advices or suggestions?

    Thank you
    With best regards,
    Alexey Kakunin
    EmForge: Liferay based project hosting service

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Each process instance has an id - you can use that to get a hold of an instance. If you need something else then the utility methods on the JbpmTemplate, use the Callback and there get a hold of the instance and call the methods you need.
    Like in most bpm solutions, the state is persisted and one has to request the engine for an instance each time he/she want to work on it, instead of carrying the instance around.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Apr 2006
    Location
    Saint-Petersburg, Russia
    Posts
    50

    Default That the reason to create JbpmContext every time?

    Costin,
    Thank you for your answers.
    I looked more into my tests and usage of JbpmTemplate and found that I was write... my code (started from m_template.getProcessDefinition().createInstance() ) lived in one JbpmContext (to say truth it works without any JbpmContext!) and code performed in JbpmTemplate lived in another - everytime created context...

    It is not very comfortable, because in massive usage of Jbpm operations (like in my tests) I should wrap WHOLE code with m_template.execute() wrapper and use bpm context I've got...

    So, in this case usage of JbpmTemplate is not very comfortable and only one reason that I can see - it solves initial problem with multiple context creation in one test suite...

    Maybe you have some ideas about better organization for Jbpm processes testing via junit with using Spring-Framework?
    With best regards,
    Alexey Kakunin
    EmForge: Liferay based project hosting service

  6. #6
    Join Date
    Apr 2006
    Location
    Saint-Petersburg, Russia
    Posts
    50

    Default Test Isolation

    OK, may be I need to read some more information abotu usage templates, tests and so on under Spring... but I found another problem trying to test my processes with jbpm31 spring module.

    So, here is basic class for testing processes:
    Code:
    package ru.emdev.EmDevProcesses.tests;
    
    import ...;
    
    /*AbstractTransactionalDataSourceSpringContextTests*/
    /** Basic class for Process Tests
     * 
     */
    public class AbstractProcessTest extends AbstractTransactionalDataSourceSpringContextTests {
    	private static Log log = LogFactory.getLog(AbstractProcessTest.class);
    	
    	/// template class to store jbpm template
    	/// setTemplate implemented in every test case to get 
    	/// the exactly template we are going to test
    	JbpmTemplate		m_template;
    
    	JbpmContext			m_jbpmContext;
    
    	/** Special call-back interface for performing tests
    	 * 
    	 */
    	public interface ProcessTestCallback {
    		public void doTest();
    	};
    	
    	
    	/** this function is used for performing test specified in call back class
    	 * 
    	 * This method is required for placing whole test into Jbpm context
    	 * 
    	 * @param i_callBack
    	 */
    	protected void executeTest(final ProcessTestCallback i_callBack) {
    		m_template.execute(new JbpmCallback() {
    
    			public Object doInJbpm(JbpmContext context) {
    				m_jbpmContext = context;
    				
    				try {
    					i_callBack.doTest();
    				} finally {
    					m_jbpmContext = null;
    				}
    				
    		    	return null;
    			}
    		});
    	}
    	
    	
    	protected String[] getConfigLocations() {
    		return new String[] {"ru/emdev/EmDevProcesses/tests/applicationContext.xml"};
    	}
    	
        /** Starts New Process
         * 
         * This function starts new process for m_processDef, 
         * assigns description and process owner
         * @param i_description - description for created process 
         * @param i_user - owner for created process
         * 
         * @return Start Task Instance for created Process
         */
        protected TaskInstance startProcess(String i_description,
        									String i_user) {
        	assertNotNull(m_jbpmContext);
        	assertNotNull(i_description);
        	assertNotNull(i_user);
    
        	log.info("Start new Process");
    
        	/*
        	ProcessInstance process = (ProcessInstance)m_template.execute(new JbpmCallback() {
    
    			public Object doInJbpm(JbpmContext context) {
    				context.getGraphSession().saveProcessDefinition(m_template.getProcessDefinition());
    		    	
    		    	ProcessDefinition processDef = context.getGraphSession().findLatestProcessDefinition(m_template.getProcessDefinition().getName());
    		    	ProcessInstance process = processDef.createProcessInstance();
    		    	
    		    	return process;
    			}
    		});
    		*/
        	
        	
        	m_jbpmContext.getGraphSession().saveProcessDefinition(m_template.getProcessDefinition());
        	
        	ProcessDefinition processDef = m_jbpmContext.getGraphSession().findLatestProcessDefinition(m_template.getProcessDefinition().getName());
        	ProcessInstance process = processDef.createProcessInstance();
        	
        	
        	assertNotNull(process);
        	
        	
    		//get start task
    		TaskInstance startTask = process.getTaskMgmtInstance().createStartTaskInstance();
    		assertNotNull(startTask);
    
    		// now, assign initial values to the task
    		startTask.setVariable(JbpmTaskImpl.DESCRIPTION_VARIABLE, i_description);
    		startTask.setVariable(JbpmProcessDefImpl.OWNER_VARIABLE, i_user);
    
    		return startTask;
        }
        
        /** Ends the specified task and check next task assignment
         * 
         * @param i_prevTask - task to end
         * @param i_nextTaskOwner- owner of next assigned task
         * @param i_nextTaskName - name of the next task
         * 
         * @return next task
         */
        protected TaskInstance endTask(final TaskInstance i_prevTask,
        							   String i_nextTaskOwner,
        							   String i_nextTaskName) {
        	assertNotNull(i_prevTask);
        	assertNotNull(i_nextTaskOwner);
        	assertNotNull(i_nextTaskName);
        	
        	log.info("Finish Task " + i_prevTask.getName());
    		// end task
        	i_prevTask.end();
        	
        	/*
        	m_template.execute(new JbpmCallback() {
    
    			public Object doInJbpm(JbpmContext context) {
    				context.save(i_prevTask);
    				
    				return null;
    			}
    		});
        	*/
        	
        	
    		// get current task
    		TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
    		
    		// check next node
    		checkNode(task.getToken(), i_nextTaskName);
    		
    		return task;
        }
        
        /** Ends the specified task by specified transition 
         * and check next task assignment
         * 
         * @param i_transitionName - transition to leave the node
         * @param i_prevTask - task to end
         * @param i_nextTaskOwner- owner of next assigned task
         * @param i_nextTaskName - name of the next task
         * 
         * @return next task
         */
        protected TaskInstance endTask(TaskInstance i_prevTask,
    			   					   String i_transitionName,
        							   String i_nextTaskOwner,
    			   					   String i_nextTaskName) {
        	assertNotNull(i_prevTask);
        	assertNotNull(i_transitionName);
        	assertNotNull(i_nextTaskOwner);
        	assertNotNull(i_nextTaskName);
        	
    		// end task
        	i_prevTask.end(i_transitionName);
    
        	//m_jbpmContext.save(i_prevTask);
        	
    		// check next node
    		checkNode(i_prevTask.getToken(), i_nextTaskName);
    		
    		// get current task
    		TaskInstance task = getOneTask(i_nextTaskOwner, i_nextTaskName);
    		
    		return task;
        }
        /** check the node for specified token 
         * 
         * @param i_token token to check
         * @param i_nodeName - name of expected node
         */
        protected void checkNode(Token i_token, String i_nodeName) {
        	assertNotNull(i_token);
        	assertNotNull(i_nodeName);
        	
    		Node node = i_token.getNode();
    		assertNotNull(node);
    		
    		assertEquals(i_nodeName, node.getName());
        }
        
        /** Checks that specified user has only one task with specified name and returns this task
         * 
         * @param i_user - user to check
         * @param i_taskName - expected task name
         * 
         * @return expected task
         */
        protected TaskInstance getOneTask(String i_user, String i_taskName) {
        	assertNotNull(m_jbpmContext);
        	assertNotNull(i_user);
        	assertNotNull(i_taskName);
        	
    		//List tasks = m_template.findTaskInstances(i_user);
        	List tasks = m_jbpmContext.getTaskMgmtSession().findTaskInstances(i_user);
    		assertNotNull(tasks);
    		
    		assertEquals(i_user + " should have only 1 task",
    					 1,
    					 tasks.size());
    		
    		TaskInstance task = (TaskInstance)tasks.get(0);
    		assertNotNull(task);
    		
    		//check task instance name
    		assertEquals(i_taskName, task.getName());
        	
    		return task;
        }
        
        /** Checks that specified user has not active tasks assigned to him
         * 
         * @param i_user - user to check
         */
        protected void checkNoTasks(String i_user) {
        	assertNotNull(m_jbpmContext);
        	assertNotNull(i_user);
        	
    		// user akakunin should have no tasks
    		//List tasks = m_template.findTaskInstances(i_user);
        	List tasks = m_jbpmContext.getTaskMgmtSession().findTaskInstances(i_user);
        	
    		assertEquals(i_user + " should have no task",
    				 0,
    				 tasks.size());
        }
    }
    What actually it did:
    • Inherited from AbstractTransactionalDataSourceSpringContextTests for transactions support
    • Declare special callback class for executing test code
    • Declare function, that executes specified in callback code inside JbpmContext. Before execution it gets JbpmContext variable to use it in test, and after execution it set it to null


    Test derived from this class looks like:
    Code:
    package ru.emdev.EmDevProcesses.tests;
    
    public class ToDoProcessTestCase extends AbstractProcessTest {
    	public void setTodoTemplate(JbpmTemplate i_template) {
    		m_template = i_template;
    	}
    
    	public void testShortWay() {
        	executeTest(new ProcessTestCallback() {
    		public void doTest() {
    
    		//get start task
    		TaskInstance startTask = startProcess("Do something!", "somebody");
    
    		TaskInstance nextTask = endTask(startTask, "somebody", "Assign ToDo");
    		assertNotNull(nextTask);
    
                    // ...
    		// do something extra
                    // ...
    			}
    		});
    	}
    
    	public void testReject() {
        	executeTest(new ProcessTestCallback() {
    		public void doTest() {
    			
    		//get start task
    		TaskInstance startTask = startProcess("Do something!", "somebody");
    
    		TaskInstance nextTask = endTask(startTask, "somebody", "Assign ToDo");
    		assertNotNull(nextTask);
    
                    // ...
    		// do something extra
                    // ...
    		}});
    	}
    }
    So, it work quite fine and solves all problem I had before:
    • No problem with jbpm configuration I initially had
    • Whole test code is performed in one JbpmContext, so it works


    In my console I can see followed strings:
    Code:
    5989 [main] INFO  ru.emdev.EmDevProcesses.tests.ToDoProcessTestCase  - Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@1570c24]; default rollback = true
    5989 [main] INFO  ru.emdev.EmDevProcesses.tests.AbstractProcessTest  - Start new Process
    6560 [main] INFO  ru.emdev.EmDevProcesses.tests.ToDoProcessTestCase  - Rolled back transaction after test execution
    So, seems transactions works... but.... I have no test isolation! Task created,assigned to somebody and not closed in one test still assigned in another

    Oh... seems all these staff should make our life easily... But I already spent too much time trying to make my working non-spring based working tests working in spring-based environment... May be I do something totally wronge?
    Are somethere any workable example available?

    Thank you for any advice!
    With best regards,
    Alexey Kakunin
    EmForge: Liferay based project hosting service

  7. #7
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Alexey, your problem is with Jbpm then Spring Modules jbpm support. Spring Modules offers just a wrapper around Jbpm. I suggest you take this issue with jbpm mailing lists. Try for example to acheive the same functionality with plain jbpm and see how easy/complicated it is compared to the one you have right now.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  8. #8
    Join Date
    Jun 2006
    Location
    Maryland
    Posts
    22

    Question

    I am having a similiar issue, I am trying to use the unit tests from the cvs.
    For example when I run JbpmObjectFactoryTests (from cvs)
    I get the stracktrace below. Oddly enough the JbpmFactoryLocatorTests works produces no errors or exceptions :

    Do I have explicitly to null out jbpmConfiguration?


    testCreateObject(com.aaxistechnologies.workflow.Jb pmObjectFactoryTest) Time elapsed: 0.276 sec <<< ERROR!
    org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'jbpmConfiguration' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    Caused by: java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.addToMap(JbpmFactoryLocator.java:108)
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.setBeanFactory(JbpmFactoryLocator.java:76)
    at org.springmodules.workflow.jbpm31.LocalJbpmConfigu rationFactoryBean.setBeanFactory(LocalJbpmConfigur ationFactoryBean.java:70)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:863)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:393)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:257)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:168)
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:248)
    at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:332)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:92)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:77)
    at org.springframework.test.AbstractSpringContextTest s.loadContextLocations(AbstractSpringContextTests. java:130)
    at org.springframework.test.AbstractDependencyInjecti onSpringContextTests.loadContextLocations(Abstract DependencyInjectionSpringContextTests.java:224)
    at org.springframework.test.AbstractSpringContextTest s.getContext(AbstractSpringContextTests.java:110)
    at org.springframework.test.AbstractDependencyInjecti onSpringContextTests.setUp(AbstractDependencyInjec tionSpringContextTests.java:192)
    at junit.framework.TestCase.runBare(TestCase.java:125 )
    at org.springframework.test.ConditionalTestCase.runBa re(ConditionalTestCase.java:69)
    at junit.framework.TestResult$1.protect(TestResult.ja va:106)
    at junit.framework.TestResult.runProtected(TestResult .java:124)
    at junit.framework.TestResult.run(TestResult.java:109 )
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:2 08)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.maven.surefire.junit.JUnitTestSet.execu te(JUnitTestSet.java:210)
    at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.executeTestSet(AbstractDirectoryTestSuite .java:135)
    at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.execute(AbstractDirectoryTestSuite.java:1 22)
    at org.apache.maven.surefire.Surefire.run(Surefire.ja va:129)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.maven.surefire.booter.SurefireBooter.ru nSuitesInProcess(SurefireBooter.java:225)
    at org.apache.maven.surefire.booter.SurefireBooter.ma in(SurefireBooter.java:747)

    testHasObject(com.aaxistechnologies.workflow.JbpmO bjectFactoryTest) Time elapsed: 0.158 sec <<< ERROR!
    org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'jbpmConfiguration' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    Caused by: java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.addToMap(JbpmFactoryLocator.java:108)
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.setBeanFactory(JbpmFactoryLocator.java:76)
    at org.springmodules.workflow.jbpm31.LocalJbpmConfigu rationFactoryBean.setBeanFactory(LocalJbpmConfigur ationFactoryBean.java:70)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:863)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:393)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:257)
    at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:168)
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:248)
    at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:332)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:92)
    at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:77)
    at org.springframework.test.AbstractSpringContextTest s.loadContextLocations(AbstractSpringContextTests. java:130)
    at org.springframework.test.AbstractDependencyInjecti onSpringContextTests.loadContextLocations(Abstract DependencyInjectionSpringContextTests.java:224)
    at org.springframework.test.AbstractSpringContextTest s.getContext(AbstractSpringContextTests.java:110)
    at org.springframework.test.AbstractDependencyInjecti onSpringContextTests.setUp(AbstractDependencyInjec tionSpringContextTests.java:192)
    at junit.framework.TestCase.runBare(TestCase.java:125 )
    at org.springframework.test.ConditionalTestCase.runBa re(ConditionalTestCase.java:69)
    at junit.framework.TestResult$1.protect(TestResult.ja va:106)
    at junit.framework.TestResult.runProtected(TestResult .java:124)
    at junit.framework.TestResult.run(TestResult.java:109 )
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:2 08)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.maven.surefire.junit.JUnitTestSet.execu te(JUnitTestSet.java:210)
    at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.executeTestSet(AbstractDirectoryTestSuite .java:135)
    at org.apache.maven.surefire.suite.AbstractDirectoryT estSuite.execute(AbstractDirectoryTestSuite.java:1 22)
    at org.apache.maven.surefire.Surefire.run(Surefire.ja va:129)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.maven.surefire.booter.SurefireBooter.ru nSuitesInProcess(SurefireBooter.java:225)
    at org.apache.maven.surefire.booter.SurefireBooter.ma in(SurefireBooter.java:747)

  9. #9
    Join Date
    Jun 2006
    Location
    Maryland
    Posts
    22

    Default

    Just to add some thoughts. I think my main issue is with the way junit creates new objects for each test method , it does not seem to release the application context between tests. Conversly, making the applicationContext static in a parent test class didn't make the error go away either. Maybe I'll have to skip the tests for now and see if I can get it working as an app.

  10. #10
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    You have to clear the map or have the bean static - the problem is that jbpm in its core uses static fields so the support classes have to be statical also - when using junits (and new objects are created) the static fields create subtle errors - if you look at the trace two values are registered for the same key inside a static map:

    Caused by: java.lang.IllegalArgumentException: a beanFactoryReference already exists for key jbpmConfiguration
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.addToMap(JbpmFactoryLocator.java:108)
    at org.springmodules.workflow.jbpm31.JbpmFactoryLocat or.setBeanFactory(JbpmFactoryLocator.java:76)
    Can you post some snippets from your tests?
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •