cancel
Showing results for 
Search instead for 
Did you mean: 

Python Scrits

johnambrosiano
Champ in-the-making
Champ in-the-making
What's the trick for getting Python scripts enabled in script tasks. I set the scriptFormat value to "python" and it tells me "Can't find scripting engine for 'python'"
14 REPLIES 14

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi John,

the problem could be:
http://activiti.org/userguide/index.html#bpmnScriptTask

The value of the scriptFormat attribute must be a name that is compatible with the JSR-223 (scripting for the Java platform). By default JavaScript is included in every JDK and as such doesn’t need any additional jars. If you want to use another (JSR-223 compatible) scripting engine, it is sufficient to add the corresponding jar to the classpath and use the appropriate name. For example, the Activiti unit tests often use Groovy because the syntax is pretty similar to that of Java.

Do note that the Groovy scripting engine is bundled with the groovy-all jar. Before version 2.0, the scripting engine was part of the regular Groovy jar. As such, one must now add following dependency:…

Regards
Martin

johnambrosiano
Champ in-the-making
Champ in-the-making
Thanks, Martin. I've seen this before. An example for Python would be helpful. Do you or anyone else know of such an example?

vasile_dirla
Star Contributor
Star Contributor
Hi John,
you could use Jython in order to call python scripts.
As of Jython 2.5.1 an implementation of JSR 223 is bundled in jython.jar. Simply add jython to your CLASSPATH and ask for the python script engine as you already mentioned above: "set the scriptFormat value to "python""
http://www.jython.org/

johnambrosiano
Champ in-the-making
Champ in-the-making
Thanks, Vasile. I'll try it.

johnambrosiano
Champ in-the-making
Champ in-the-making
Vasile,

Did as you suggested. (1) Using the Activiti Designer Eclipse plugin. (2) Have jython 2.7.0 in the POM for the project.

(3) Defining the following in the script task in the process:

  <scriptTask id="scripttask1" name="Script Task"
   activiti:autoStoreVariables="false" scriptFormat="python">
   <script>
    print "Hello"
   </script>
  </scriptTask>

(4) Invoking with:

public void startScript() {
  ProcessEngine processEngine = ProcessEngineConfiguration
   .createStandaloneInMemProcessEngineConfiguration()
    .buildProcessEngine();   
  RuntimeService runtimeService = processEngine.getRuntimeService();
  RepositoryService repositoryService = processEngine.getRepositoryService();
  repositoryService.createDeployment()
   .addClasspathResource("diagrams/HelloScript.bpmn")
   .deploy();
  ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
    "helloScript");
}

(5) Getting these errors:

org.activiti.engine.ActivitiException: Can't find scripting engine for 'python'
at org.activiti.engine.impl.scripting.ScriptingEngines.getEngineByName(ScriptingEngines.java:124)
at org.activiti.engine.impl.scripting.ScriptingEngines.evaluate(ScriptingEngines.java:85)
at org.activiti.engine.impl.scripting.ScriptingEngines.evaluate(ScriptingEngines.java:73)


What am I missing? Thanks.

vasile_dirla
Star Contributor
Star Contributor
Hi,
just create a unit test to demonstrate what's not working and upload it here (rename the zip extension to txt in order to upload it)

johnambrosiano
Champ in-the-making
Champ in-the-making
Thanks, Vasile,

Here's a diagram, a test, and the POM file to show the dependencies I've included.

vasile_dirla
Star Contributor
Star Contributor
Hi,
I don't have knowledge of python but during the debug I see that the engine cannot import the 'site' module so I decided to disable this (I have no idea what's the impact over the python engine so maybe if you know more about python you can add some more info here.)

https://docs.python.org/2/library/site.html

Anyway.. back to Jython JSR 223 support:
I did a few changes to your code and now it works:
<code>
@Test
@Deployment(resources = {"diagrams/HelloScript.bpmn"})
public void startScript() {

  Properties props = new Properties();
  props.put("python.import.site","false");
  Properties preprops = System.getProperties();
  PythonInterpreter.initialize(preprops, props, new String[0]);

  ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("helloScript");
  assert(processInstance.getDeploymentId()!=null);
}
</code>


and also changed the script of your ScriptTask to:
<code>
<script>import sys; a = 42; print a; x = 2 + 2; print "x:",x</script>
</code>

and i can see this result:
<code>
INFO: Processing resource diagrams/HelloScript.bpmn
42
x: 4
</code>

so.. it's working.

There are a few issues as i can see with Jython, if the script contains new lines, it will fail when parsing. Smiley Happy
Will be nice if we'll find a nice solution for python scripts in Activiti even that means we'll put some code into Jython or just change it with something else.

Thank you for posting the code to initialize the Jython runtime!  That was quite helpful. 

There are a couple of additional pieces of information that might help others.  First, it seems like the issue about the "python.import.site" property is discussed in this defect in the Jython project:  http://bugs.jython.org/issue2355

Second, I was able to work around the indenting issue like this:

<blockcode>
            <script>
<![CDATA[
import sys

a = 42

print a

x = 2 + 2

print "x: ", x
]]>
            </script>
</blockcode>

The problem is that indenting is important to Python and what looks normal in XML will not run in Python because of the leading indentation.

Hope this helps.