cancel
Showing results for 
Search instead for 
Did you mean: 

Script evaluation in a separated thread

mathiasd
Champ in-the-making
Champ in-the-making
Hi,
Is it possible to run script evaluations in a separated thread ? I made my own script engine which uses the javascript engine.
I have something like that :


public Object eval(String script, Bindings n) throws ScriptException {
        ScriptThread thread = new ScriptThread(javascriptEngine,script,n);
        thread.start();
        long startTime = System.currentTimeMillis();
        while(System.currentTimeMillis()-startTime < 10000 && thread.getResult() == null);
        Object result = thread.getResult();
        if(result == null) {
            throw new ScriptException("Script execution was too long");
        }
        return result;

And the scriptThread is simply :

@Override
    public void run() {
        try {
            result = engine.eval(script, bindings);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

But when I run this code I have :

Exception in thread "Thread-2" java.lang.NullPointerException
   at org.activiti.engine.impl.scripting.BeansResolverFactory.containsKey(BeansResolverFactory.java:30)
   at org.activiti.engine.impl.scripting.ScriptBindings.containsKey(ScriptBindings.java:52)
   at javax.script.SimpleScriptContext.getAttributesScope(Unknown Source)
   at com.sun.script.javascript.ExternalScriptable.put(Unknown Source)
   at com.sun.script.javascript.RhinoScriptEngine.getRuntimeScope(Unknown Source)
   at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
   at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
   at javax.script.AbstractScriptEngine.eval(Unknown Source)
   at xxx.ScriptThread.run(ScriptThread.java:23)

The line where the exception is thrown is (in BeansResolverFactory.java:30) :

return Context.getProcessEngineConfiguration().getBeans().containsKey(key);

And this is "Context.getProcessEngineConfiguration()" which returns "null". Here's the code of this part in 'Context.java:38' :


public static ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
     Stack<ProcessEngineConfigurationImpl> stack = getStack(processEngineConfigurationStackThreadLocal);
    if (stack.isEmpty()) {
      return null;
    }
    return stack.peek();
}

Do you have any idea to perform this ?
2 REPLIES 2

trademak
Star Contributor
Star Contributor
Hi,

In the current trunk of Activiti you can make use of async continuations.
This means that you can execute a specific task asynchronous. Is that what you're looking for?

Best regards,

mathiasd
Champ in-the-making
Champ in-the-making
Not sure. Actually I'm trying to add some protections in my workflows.
For example I want to protect my workflow engine against infinite loops in script tasks. That's why I want to start the eval method in a separated Thread and interrupt this Thread if the evaluation is too long.

Actually I found the problem, I just add :

Context.setProcessEngineConfiguration(config);
Context.setCommandContext(commandContext);
before evaluation. Now I throw a ScriptException if the script is too long. My new problem (Smiley Very Happy) is that after the exception is thrown, the script seems to be still running (JavaVM still take 100% of the CPU).

Maybe you know a better solution to implement this "watchdog" ?