Groovy files can't invoke methods in other groovy files which are part of same deployment

As part of our process, we deploy the BPMN and associated groovy scripts using DeploymentBuilder and RepositoryService. We do this by exposing a REST endpoint. The groovy can be accessed by adding the namespace “deployment://”.

Now we want to allow users which have large complex BPMNs with many groovy scripts, to make use of common code, so that they don’t have to duplicate methods in groovy scripts. But the way we have allowed deployment, the groovy scripts cannot access methods in other files which part of that deployment.

To test, I added the common groovy code as part of our resources and deployed the BPMN with groovy scripts and these scripts could access the common files.

Is there a way to deploy groovy files and have them access each other at run time?

You could deploy your groovy packages as part of the libs folder in your application, so then you can use import to import the packages into the scripts.

side note that Nashorn (javascript) works much better for scripting in the scenario you have mentioned. You can easily use scripts and load additionals using load() function in nashorn.

I dont know what groovy has for executing new script code during runtime, but assuming that it has something you could convert my Nashorn code into Groovy code: https://github.com/StephenOTT/ProcessProjectTemplate/blob/master/docs/helpers.md#load-deployment-resource-into-memory

This code allows you to access a deployment resource and get the resource as a String. You would then send the String into whatever “thing” in groovy would be executing the extra code.

1 Like

Thanks Stephen,
I will check if there is a way to initialize code as string.

Ya looks like you can do this with groovy shell http://docs.groovy-lang.org/latest/html/api/groovy/lang/GroovyShell.html

You will likely have to pass things like execution and S()/spin into the shell

Here is the Groovy example:

static def getScript(fileName, execution) {
    def processDefinitionId = execution.getProcessDefinitionId()
    def deploymentId = execution.getProcessEngineServices().getRepositoryService().getProcessDefinition(processDefinitionId).getDeploymentId()
    def resource = execution.getProcessEngineServices().getRepositoryService().getResourceAsStream(deploymentId, fileName)

    def scannerResource = new Scanner(resource, 'UTF-8')

    def resourceAsString = scannerResource.useDelimiter('\\Z').next()
    scannerResource.close()

    GroovyShell shell = new GroovyShell()
    return shell.parse(resourceAsString)
}

def helper = getScript("helpers/helper_classes.groovy", execution)

To include general code needs a lot of boilerplate!

I think this should be improved. Something like this would be great:

GroovyShell shell = new GroovyShell()
def helper = shell.parse("deployment://helpers/helper_classes.groovy")
1 Like