cancel
Showing results for 
Search instead for 
Did you mean: 

Passing parameters to Java classes

borisjan
Champ in-the-making
Champ in-the-making
Hi,

I have read the documentation to my best ability but still is not sure how to do the following (if possible at all):

I would like to execute Java code (service task) passing in a variable number of possible varying parameters. I.e. a set of name/values that the Java code would use for its execution. The variables should not be global since this would pollute the process context and I might want to call the Java task a number of times with varying values.. As far as I can see the injection mechanism require named fields in the Java class corresponding to parameters stated in the process definition so that won't do the trick for me..

Any suggestions? Is this possible at all in Activiti/BPMN 2.0?

I looked at the scripting task and as far as I can see it does not support passing in parameters to the script but only using "global" process variables.
12 REPLIES 12

plehal
Champ in-the-making
Champ in-the-making
you can use org.activiti.engine.delegate.Expression to pass any variables to the java class implementing JavaDelegate and set the  variables on the flow event (take).

frederikherema1
Star Contributor
Star Contributor
You can use the Service-task fields to add values to a service-task. Indeed, these values CAN be process-variables, but not limited to that. For example, you can pass in literal values (e.g. "myString") or numbers (${12345}). On top of that, you should have a "service" provide those variables, by exposing a bean to alfresco that provides these variables. Than you can use "${myBean.getValueToUse()}" as value for the activiti:field.

In case this doesn't meet your requirements, you can always do the following:

  • Create a sub-process around the part of the process you want to have "local" variables for

  • Subprocess creates an additional variable-scope.

  • Set variables on the sub-process scope using DelegateExecution.setVrariablesLocal() inside the process, or use the runtimeService.setVariablesLocal() from outside the process

  • Once the sub-process completes, the scow is destroyed and all LOCAL variables are removed, not polluting the mail process variables

borisjan
Champ in-the-making
Champ in-the-making
Thanks for your valuable feedback.

As far as I understand your suggestions I still need to use the field injection mechanism which require that my Java class has explicit fields defined in advance and these field names must correspond to the field names I am conveying. Thus the code below only work if my class define the filterClass field of type engine.delegate.Expression.

    <serviceTask id="facadefilter" name="FacadeTest" activiti:class="com.agetor.bpm.bridge.FilterFacade">
      <extensionElements>
        <activiti:field name="filterClass">
          <activiti:string>com.agetor.bpm.bridge.SimulatedFilter</activiti:string>
        </activiti:field>


That is my core problem. I have some legacy Java classes that receive a Properties object filled with name/value pairs that were previously collected from some XML similar to tat of BPMN but that engine conveyed the parameters/fields as a method parameter object. So now I may looking for a work-around of some sort here.

All my problems would be solved i only the field-mechanism could work without injecting into class fields but simply provide the name/values of the field thorough the DelegateExecution context object where I would iterate around them and pick what I liked 🙂

I also thought about the sub-process solution but it seems like stretching things very far and making diagram unnecessarily complex. And I am not sure if your suggestion implies that I would have to set variables programmatically before running the process? My goal i to state the complete execution in a BPMN 2.0 (including parameters for the Java tasks).

I don't suppose the data input/output of BPMN 2.0 would be any help to me here? or that it is yet supported by Activiti?

frederikherema1
Star Contributor
Star Contributor
Without using the process-variables, I'm afraid storing stuff on the DelegateExecution will be hard. Just thinking with you here, don't take this as "best practice for activiti", some of the workaround I think of, if I get your use case correctly.

Solution one:
  • For EACH of your existing java-beans, write a wrapper JavaDelegate that just evaluates the expressions and put's them all in a map. This map is passed on to your existing java)bean.
Solution two:
  • Create a generic JavaDelegate (eg. MapPassingJavaDelegate). This has two activiti:field's: parameterMap and wrappenBeanReferende

  • The mappedBeanReference is a string, identifying which of your beans you want to use (classname, lookup, …)

  • The parameterMap is a sting-property:

  • <activiti:field name="parameterMap">
            <activiti:string>
              <![CDATA[
                   {
                         param1 : "theParam",
                         param2: true,
                         param3: 12345
                   }
              ]]>
          </activiti:string>
        </activiti:field>

  • Parse the JSON from the field in your MapPassingJavaDelegate, generating a raw hash map with the values (use org.json.simple.JSONObject, this extends HashMap and needs no conversion to pass into your beans) and pass on the the looked-up legacy-bean

  • You can also use variables in the JSON, just add JUEL-statements in the CDATA-body and use "expression" instead of "string" for the field

borisjan
Champ in-the-making
Champ in-the-making
Thanks again for your time.

Yes, your second suggestion would probably do the trick! I.e. allow me to pass name/values without hard bindings to instance variables. I will continue experimenting with this and hope that I can end up with a proof-of-concept allowing fragments of our current functionality to run within the realm of your interesting and powerful engine 🙂

frederikherema1
Star Contributor
Star Contributor
Cool. If possible, you can always post your POC-code on the forum, always interested in these kind of solutions

rajkumararumuga
Champ in-the-making
Champ in-the-making
Hi,

I would like to do passing value from java to activiti workflow. for that i am using java class

public class initListener implements JavaDelegate{



@Override
public void notify(DelegateTask task) {
  try {
    
   String name="activiiti";
   System.out.println("namevalue####" + name);
    DelegateExecution execution = task.getExecution();
    execution.setVariable("values", execution);
    System.out.println("execution value &&&&&&" + execution); 
   
       
  }catch(Exception e){
   System.out.println("error" + e);
  }


}

@Override
public void notify(DelegateExecution arg) throws Exception {
  String name="activiiti";
  arg.setVariable("test", name);
  System.out.println("namevalue####" + name);
  
  
  
}

@Override
public void execute(DelegateExecution arg0) throws Exception {
 
 
}

}

Then  in the workflow i am trying to get the value from script task like
<script name="groovy">
println "expected ans is  ${val}"
</script>

I could not get proper output ..
Any one help me what mistake i have done. ?

rajkumararumuga
Champ in-the-making
Champ in-the-making
Anyone tell me
After Starting the process in workflow can we pass the value to whole workflow .. ?
that is user task and service task like that …

rajkumararumuga
Champ in-the-making
Champ in-the-making
Hi,

Is it possible to pass the value to activiti while starting process, then throughout i can use the value in the workflow. If anyone knows please help me. thanks for the advance..