cancel
Showing results for 
Search instead for 
Did you mean: 

write and read a variable from an object

tomi87
Champ in-the-making
Champ in-the-making
I don't know why it's doesn't work, to write the variable in the object and then to read it.

   <userTask id="chooseAddName" name="Choose add Name" activiti:candidateGroups="st">
         <extensionElements>
            <activiti:formProperty id="addName" name="Add name" expression="#{stAppInfo.addName}" required="true" />
         </extensionElements>
      </userTask>

I test it with this input:

StAppInfo stInfo= new StAppInfo ();
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("stAppInfo ", stInfo);
variables.put("addName", "Bernd Hauch");


If I ask which addName is inside it gives me null:
assertEquals("Bernd Hauch", stInfo.getAddName());

Why?
25 REPLIES 25

frederikherema1
Star Contributor
Star Contributor
Are you using runtimeService.startProcess() or formService.submitStartForm()? Because, when you're using plain "startProcess", you're just submitting RAW variables, the form-properties definitions are ignored.

tomi87
Champ in-the-making
Champ in-the-making
Ok now I'm using  FormService formService = activitiRule.getFormService();


StAppInfo stInfo= new StAppInfo ();
Map<String, Object> variables = new HashMap<String, Object>();

stInfo.setStName("June Muller");

variables.put("stAppInfo ", stInfo);
variables.put("addName", "Bernd Hauch");
 
formService.submitStartFormData(definition.getId(), variables);
But how can I submit this now ?
If I select this then I have to submit a Map<String, Object> and a Map<String, String> .
But how can I submit then two with the submitStartFormData? Or how can I just submit my Map<String, Object> variables ?

The method submitStartFormData(String, Map<String,String>) in the type FormService is not applicable for the arguments (String, Map<String,Object>)

frederikherema1
Star Contributor
Star Contributor
Form-properties have a couple of string->object conversions out of the box: date, long, … If you want to use another type of "form property", you can create custom types. However, the form-properties are intended to be used in combination with form-technologies. If you want to populate the process vita stuff that does not come from a form (e.g.. a new instance of StAppInfo), you should just use startProcess(…) and pass in the map<string, object>.

Later on in the process, you can have TASK-forms that can use the stdAppInfo-pojo in their form-properties.

tomi87
Champ in-the-making
Champ in-the-making
ok. When I go back to my question:
If I ask which addName is inside it gives me null:
assertEquals("Bernd Hauch", stInfo.getAddName());
How can I fix that now, when the method submitStartFormData(String, Map<String,String>) says that I can't use my variables to submit it?
Variables:
StAppInfo stInfo= new StAppInfo ();
Map<String, Object> variables = new HashMap<String, Object>();
stInfo.setStName("June Muller");
variables.put("stAppInfo ", stInfo);
variables.put("addName", "Bernd Hauch");

I don't understand it.

tomi87
Champ in-the-making
Champ in-the-making
I tried it now like this: But I get still an error message


       FormService formService = activitiRule.getFormService();
  TaskService taskService = activitiRule.getTaskService();
  RuntimeService runtimeService = activitiRule.getRuntimeService();
 
                Map<String, Object> variables = new HashMap<String, Object>();
  StAppInfo stInfo= new StAppInfo ();
                variables.put("stAppInfo ", stInfo);

runtimeService.startProcessInstanceByKey("part1XorAdvisor", variables);     //NullPointerException
   
  Task task = taskService.createTaskQuery().singleResult();
  Map<String, String> formProperties = new HashMap<String, String>();
  formProperties.put("addName", "Bernd Hauch");
  formProperties.put("addEmail", "addr@email.de"); 
  formProperties.put("requestAccepted", "true"); // Test with input == true

formService.submitTaskFormData(task.getId(), formProperties);
 
  assertEquals("searchANameAsAdd", task.getTaskDefinitionKey());
  System.out.println("should be Bernd Hauch: " + studentInfo.getAdvisorName());  //but is null

jbarrez
Star Contributor
Star Contributor
Where is the 'studentInfo' variable coming from? It would be easier for us if you could provide a simple unit test.

tomi87
Champ in-the-making
Champ in-the-making
"studentInfo" variable is a writing mistake.

here again my bpmn20.xml, my test and the error message:

bpmn20.xml:
<process id="part1ChooseAdd">
  <startEvent id="start"></startEvent>
  <sequenceFlow id="flow129" sourceRef="start"
   targetRef="searchAPrAsAdd"></sequenceFlow>
  <userTask id="searchAPrAsAdd" name="search a pr as add"
   activiti:candidateGroups="student">
   <extensionElements>
    <activiti:formProperty id="addName" name="Add name"
     expression="#{stAppInfo.addName}" required="true" />
    <activiti:formProperty id="addEmail" name="Add Email"
     expression="#{stAppInfo.addEmail}" required="true" />
   </extensionElements>
  </userTask>
  <sequenceFlow id="flow2" name="" sourceRef="searchAPrAsAdd"
   targetRef="theEnd"></sequenceFlow>
  <endEvent id="theEnd"></endEvent>

My Test:
public class ChooseAddTest {

@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti.cfg-mem.xml");
@Autowired
private RuntimeService runtimeService;

@Autowired
private TaskService taskService;

@Autowired
private FormService formService;
@Test
// deploys process with form properties
@Deployment(resources = { "part1Application/chooseAdd.bpmn20.xml" })
public void testChooseAdd() {

  Map<String, Object> variables = new HashMap<String, Object>();
  stAppInfo studentInfo = new stAppInfo();
  variables.put("stAppInfo", studentInfo);
  runtimeService.startProcessInstanceByKey("part1ChooseAdd", variables);

  Task task = taskService.createTaskQuery().singleResult();

  Map<String, String> formProperties = new HashMap<String, String>();
  formProperties.put("addName", "Bernd Hauch");
  formProperties.put("addEmail", "advisorATemail.com");
  formService.submitTaskFormData(task.getId(), formProperties);
 

  System.out.println("sould be Bernd Hauch: " + studentInfo.getaddName());
}
}

error message:  (ChooseAddTest.java:66) is runtimeService.startProcessInstanceByKey("part1ChooseAdd", variables);
java.lang.NullPointerException
at org.bpmwithactiviti.part1ApplicationTest.ChooseAddTest.testChooseAdd(ChooseAddTest.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.rules.TestWatchman$1.evaluate(TestWatchman.java:48)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
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)

For my test:
I think that I need to submit the
Map<String, Object> variables = new HashMap<String, Object>();
stAppInfo studentInfo = new stAppInfo();
variables.put("stAppInfo", studentInfo);
because the bpmn20.xml file want to store the variable addName and addEmail in the stAppInfo Object.

Then I think I also need to submit the variable values/names
Map<String, String> formProperties = new HashMap<String, String>();
formProperties.put("addName", "Bernd Hauch");
formProperties.put("addEmail", "advisorATemail.com");

Can you explain me how this works in the right way with the "double" submitting ?

jbarrez
Star Contributor
Star Contributor
@Autowired
   private RuntimeService runtimeService;

You are trying to inject the runtime service using a Spring autowired annotation. But you arent using a spring container, but Activiti standalone.

Remove the lines above and use activitiRule.getRuntimeService() where needed.

frederikherema1
Star Contributor
Star Contributor
You're doing it the right way, only your "runtimeService" is null, that the only thing that can cause NPE on that line…
error message: (ChooseAddTest.java:66) is runtimeService.startProcessInstanceByKey("part1ChooseAdd", variables);