NPE in ScriptingEngines.getScriptEngineForLanguage() when executing outside process instance

Dear Community,

I am migrating a custom framework to Camunda 7.5.0. The framework evaluates groovy scripts outside of process instance execution (scripts are called via REST end point). I’ve discovered that on 7.5.0 the method ScriptingEngines.getScriptEngineForLanguage() throws an NPE when the framework attempts to get groovy ScriptEngine outside of process instance execution context.

java.lang.NullPointerException at org.camunda.bpm.engine.impl.scripting.engine.ScriptingEngines.getScriptEngineForLanguage(ScriptingEngines.java:101) at org.camunda.bpm.unittest.SimpleTestCase.evalGroovyWithInstanceData(SimpleTestCase.java:55)

I see that in version 7.4.0 the ScriptingEngines.getScriptEngineForLanguage() method was modified significantly, so it could be a regression.
Is there an alternative API that should be used to get a ScriptingEngine outside of process instance?

P.S. The following branch contains a standalone test case for the problem:

Thanks,
Sergii

Hi Sergii,

The class ScriptingEngines is part of the internal API, so that I would not recommend you to use that in your code base. But there is also no alternative API to use the ScriptingEngine. However, you could provide a pull request, which adds a null-check.

What is your use case? Why do want to fetch a ScriptEngine from the ProcessEngine?

Cheers,
Roman

Hi Roman,

Thank you for your reply.
The use case is to be able to execute groovy script outside of process instance, but with access to instance variables and org.camunda.bpm.engine.RuntimeService APIs.
To give you an example. Our framework is an AngularJS based cross-BPM-platform UI framework. The task and dashboard UIs build with the framework have an ability to call custom servers side groovy script via AJAX calls. The scripts can be used to update instance’s execution variables, execute Camunda’s RuntimeService APIs as well as execute a custom non-BPM logic.
It would be nice to have a public API to access Camunda’s ScriptEngines.

Thank you!
Sergii

Hi Sergii,

why don’t you call the Camunda Rest API to modify the process instances directly from the angularJS frontend?

Keep it simple…

Cheers, Ingo

Hi Sergii,

IMHO it is out of scope, that we expose the ScriptingEngines via public API. And as Ingo suggested, there other possibilities to modify the process instances from angularjs.

Cheers,
Roman

Roman, Ingo,

Thank you for the feedback. REST API accessed from angularjs directly is definitely an option. The problem with this approach that the angularjs layer will have to be changed to understand all the different kinds of BPM engines our framework supports. Besides, the groovy scripts are designed to be executed server side with access to RuntimeService API and Camunda variables being only a part of what the “Service Engine” was designed to do.

As an alternative to the internal Camunda API, we can try to use javax.script.ScriptEngineManager.getEngineByName(“groovy”) and try to push the Camunda execution and variables through the binding.

Thank you again,
Sergii

Hi Roman/Ingo,

The root of the problem here is that the following Context calls, both of which I would expect to return valid objects are returning “null”.

ProcessApplicationReference pa = Context.getCurrentProcessApplication();
ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();

We are running a basic Spring Boot application using the spring-boot-starter 1.3 and we have exposed a custom REST endpoint. Within this endpoint we want to retrieve a script engine.

While we can autowire the ProcessEngineConfiguration with no problem, we get a “null” when we try to pull it from the context.

This worked in version 7.2 but appears broken in 7.5.

Why can we not call Context.getProcessEngineCofiguration() in a very basic spring boot application from a custom REST endpoint? (remember, auto-wiring works fine)

If this isnt a bug, then it is a significant change in behavior.
Thanks,
Greg

Hi @gdharley,

Context.getProcessEngineConfiguration() requires to be executed within an active command, or else the method returns null. This works that way since 7.0, so could you please clarify what worked in 7.2 but not in 7.5 anymore?

Be aware that the class ScriptingEngines is part of the internal API which can be changed in a way so that it is not backward compatible, see also our definition of public API 1.

When you want to execute Context.getProcessEngineConfiguration() or if you want to retrieve some scripts by using ScriptingEngines then you have to take care that this is executed within an active command. As an alternative, you could also provide a pull request which adds a null check whether the process engine configuration is null or not.

Cheers,
Roman

Is there a specific reason why you don’t use the JSR 223 API instead of relying on Camunda-internal classes that only wrap this API anyway?

Hey Thorben,

Funny you should say that, we have modified the code to call the JSR223 API directly.
As for internal API, as far as I know, Camunda is still open source, meaning, there is no such thing as an internal API.

Greg Harley - BP3

getScriptEngineForLanguage() worked nicely in 7.2 and was a very useful helper class.
Look for a null check pull request so at least we fail in a predictable way.

Hi Greg,

Sorry, I should have been more clear: With internal API I mean anything that does not qualify as public API.

Edit: and this is the key point here: You can rely on Camunda public API and JSR 223 to be stable with any future versions. For anything internal (like ScriptingEngines), you cannot. I therefore advise using something that is guaranteed to remain stable.

Cheers,
Thorben