cancel
Showing results for 
Search instead for 
Did you mean: 

Problem running a simple Junit (Junit 4 style)

monika_b
Champ in-the-making
Champ in-the-making
Hi, I have wrote a simple activiti junit as below. Trying to 'run as Junit' via eclipse. I am getting exception as below. Please can someone help me. I know I am missing something at very basic level.
Please note I have included all jars in my project from activiti-5.14\libs.

Exception Below:-

java.lang.NoClassDefFoundError: org/junit/rules/TestRule
   at java.lang.ClassLoader.defineClass1(Native Method)
   at java.lang.ClassLoader.defineClass(Unknown Source)
   at java.security.SecureClassLoader.defineClass(Unknown Source)
   at java.net.URLClassLoader.defineClass(Unknown Source)
   at java.net.URLClassLoader.access$100(Unknown Source)
   at java.net.URLClassLoader$1.run(Unknown Source)
   at java.net.URLClassLoader$1.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at java.lang.Class.getDeclaredFields0(Native Method)
   at java.lang.Class.privateGetDeclaredFields(Unknown Source)
   at java.lang.Class.getDeclaredFields(Unknown Source)
   at org.junit.runners.model.TestClass.<init>(TestClass.java:40)
   at org.junit.runners.ParentRunner.<init>(ParentRunner.java:65)
   at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:59)
   at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
   at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
   at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: org.junit.rules.TestRule
   at java.net.URLClassLoader$1.run(Unknown Source)
   at java.net.URLClassLoader$1.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   … 31 more



import org.activiti.engine.RuntimeService;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;

public class TestMyProcess{
   @Rule
   public ActivitiRule activitiRule = new ActivitiRule();
   
   @Test
   @Deployment
   public void testMyProcess()
   {
       RuntimeService runtimeService = activitiRule.getRuntimeService();
       runtimeService.startProcessInstanceByKey("myProcess");
       System.out.println("Completed Test Activiti");
   }
}


My Simple myProcess.bpmn20.xml is below:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="Service Task" activiti:class="com.companyName.activiti.common.JavaActService1"></serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="350.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
        <omgdc:Bounds height="55.0" width="105.0" x="600.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="930.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="385.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="600.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="705.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="930.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>


I am having proceeses.xml with above bpmn xml file as below:

<?xml version="1.0" encoding="utf-8" ?>
<processes>
        <process resource="diagrams/MyProcess.bpmn20.xml" />
</processes>



Some basic question. Please help.

Do I need to put some code somewhere in my junit class similar to:
<b>repositoryService.createDeployment().addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml").deploy();<b>

If not, How do the junit deploy the process otherwise. If yes, please help how to do so.


Thanks in advance for any help.
12 REPLIES 12

monika_b
Champ in-the-making
Champ in-the-making
I tried replacing public ActivitiRule activitiRule = new ActivitiRule(); with public ActivitiRule activitiRule = new ActivitiRule("activiti-context.xml"); also. Still same exception.

I am using Junit 4.8.1 jar. Seems this does not contain TestRule class. and Junit-4.9.jar contains this. I tried downloading and adding this jar to my project now getting exception as:
<code>
java.lang.Exception: Field activitiRule must implement MethodRule
at org.junit.runners.BlockJUnit4ClassRunner.validateRuleField(BlockJUnit4ClassRunner.java:181)
at org.junit.runners.BlockJUnit4ClassRunner.validateFields(BlockJUnit4ClassRunner.java:176)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:116)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:269)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:66)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:59)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
</code>

My activiti-context.xml is
<code>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                           http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  <property name="dataSource" ref="myDataSource" />
  <property name="transactionManager" ref="transactionManager" />
  <property name="databaseSchemaUpdate" value="true" />
  <property name="jobExecutorActivate" value="false" />
</bean>

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>

<bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule">
  <property name="processEngine" ref="processEngine" />
</bean>

<bean id="repositoryService" factory-bean="processEngine"
  factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine"
  factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine"
  factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine"
  factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine"
  factory-method="getManagementService" />
</beans>
</code>
Please guide me running a simple junit class. Many thanks for any help.

frederikherema1
Star Contributor
Star Contributor
We have JUnit 4.11 as dependency listed in out pom.xml. Try using that one instead

monika_b
Champ in-the-making
Champ in-the-making
I have one more Question.

As suggested we need resource file of form testClassName.testMethod.bpmn20.xml for @Deployment to work within same package as junit class.
If we have service task inside this diagram should it be referring to some test java service task or original service task ?? In this case if we perform some java code will that be reverted back after the junit runs? or please help how it actually works?

Thanks in advance.

monika_b
Champ in-the-making
Champ in-the-making
Thanks fred. It worked like a charm.

But I am trying to integrate activiti with existing WebApplication. It has junit-4.8.1.jar already added. And I am able to run Junit successfully with it if I use JUnit versions 3 styles of unit testing(extending ActivitiTestCase and not using ActivitiRule). Will that be a problem later on for some complex activiti flow?
<b>UserGuide snippet "To get the same functionality when using the JUnit 4 style of writing unit tests, the org.activiti.engine.test.ActivitiRule Rule must be used".</b>

Please suggest either case. Can I use existing junit-4.8.1.jar with junit 3 style of unit testing or should upgrade my junit jars to junit 4.11?(Latter case needs to test entire existing application is a bit of extra work)

Thanks again for help and valuable guidance. *preved* *HELLO* *PREVED* *PRIVET* *HI*

monika_b
Champ in-the-making
Champ in-the-making
I tried using original JavaService class inside testClassName.testMethod.bpmn20.xml with execution.setVariable("JavaActService1", "true"); statement.
It is getting stored in DB though I am running a Junit with @Deployment is not something we expect. Ideally it should delete all process execution/variables/instances.

User Guide Snippet
"Before the test is run, a resource file of the form testClassName.testMethod.bpmn20.xml in the same package as the test class, will be deployed. At the end of the test, the deployment will be deleted, including all related process instances, tasks, etc. "

Please help what is wrong. *secret* :-X :-x X: x: :-# :# :secret:

monika_b
Champ in-the-making
Champ in-the-making
My Junit Test classs:
<code>
public class TestMyProcess{

@Rule 
public ActivitiRule activitiRule = new ActivitiRule();

@Deployment
@Test
public void testMyProcess()
{
  RuntimeService runtimeService = activitiRule.getRuntimeService();
     ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess");
     assertNotNull("ProcessInstance should not be found null", processInstance);
     System.out.println("Completed Test MyProcess Activiti");
}
}
</code>

Java service class:
<code>
public class JavaActService1 implements JavaDelegate{

@Override
public void execute(DelegateExecution execution) throws Exception {
  execution.setVariable("JavaActService1", "true");
  System.out.println("Inside JavaActService1 class…");
}
}

</code>

My MyProcess.bpmn20.xml file is:
<code><?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="Service Task" activiti:class="com.activiti.common.JavaActService1"></serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="350.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
        <omgdc:Bounds height="55.0" width="105.0" x="600.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="930.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="385.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="600.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="705.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="930.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
</code>

Question: Do I need to manually create TestMyProcess.testMyProcess.bpmn20.xml  inside same package of junit or will autocreated by @Deployment. In either case, I dont expect Process Execution/instances/variables getting stored in ACT_* tables. But it is getting stored in both cases for me.
Please guide further what I m missing in this.

Thanks in advance,
Monika

trademak
Star Contributor
Star Contributor
You need to create TestMyProcess.testMyProcess.bpmn20.xml yourself in the same package. Or you can define the resource you want to deploy in the resources property of the @Deployment annotation. Why would you expect that nothing is store in the ACT_* tables? Running it in a unit test doesn't mean it will not get stored in the database.
If you want to rollback the transaction after your test run, you can use Spring transaction for example. We use that in our activiti-spring unit tests as well.

Best regards,

monika_b
Champ in-the-making
Champ in-the-making
Thanks for the help.

But Please would you elaborate how to rollback junit changes. I dont want to gets anything stored permanently on ACT_* DB on running junits.
My activiti.cfg.xml file is quite simple as below:

<code>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                           http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<bean id="processEngineConfiguration"
  class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
  <property name="jdbcUrl"
   value="jdbcSmiley Surprisedracle:thin:@(DESCRIPTION =(ADDRESS_LIST=(ADDRESS = (PROTOCOL = TCP)(HOST = myIpAddress)(PORT = myPortNo)))(CONNECT_DATA =(SERVER = DEDICATED)(SID = mySID)))" />
  <property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver" />
  <property name="jdbcUsername" value="abc" />
  <property name="jdbcPassword" value="abc123" />

  <property name="databaseSchemaUpdate" value="true" />
  <property name="jobExecutorActivate" value="false" />
  <property name="history" value="activity" />

  <property name="customPostDeployers">
   <list>
    <bean class="org.activiti.engine.impl.rules.RulesDeployer" />
   </list>
  </property>
</bean>
</beans>
</code>

And I am creating the processEngine using stmt as: (note, this stmt is not kept inside JUnit and not related with junit at all)
processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault().buildProcessEngine();

Please help how to use rollback my junit transactions in tihs case.

Thanks again for any help.

monika_b
Champ in-the-making
Champ in-the-making
Hey Thanks. I am able to get it inserted and rollbacked itself. I was missing few things like.
As suggested by Trade,
You need to create TestMyProcess.testMyProcess.bpmn20.xml yourself in the same package.
Name the process name as 'TestMyProcess' different from your real bpmn20.xml file.

Thanks a ton for helping a newbie in activiti.