cancel
Showing results for 
Search instead for 
Did you mean: 

Serialization bug in scripts with JDK >= 1.6.0_43

matutano6
Champ in-the-making
Champ in-the-making

Hi,

I'm using Activiti 5.17.0, and I recently upgraded to JDK 1.7 from 1.6.0_26 and reached a problem with serialization in scripts. Searching forums, I found several articles regarding the issue. Some of them are:

Bug on JDK 1.7.0_17 when using ScriptTask in Activiti | Small steps with big feet 

couldn't find a variable type that is able to serialize [object global] 'nashorn.global' 

Script Task exception serizlization 

As I could see, the issue is being workarrounded with an explicit variable set (i.e. execution.setVariable("varName", value)), but in my case, I'm using ScriptExecutionListeners, wich still seem to fall in the bug regardless the explicit variable set.

I would like to ask if there is a specific way or workarround to continue using the ScriptExecutionListeners (and ScriptTaskListeners also). At the moment, I had to extract scripts listeners to a ScriptTask, but it generates confusion in the business undertanding when viewing the BPMN model.

As Oracle removed the bug report at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=9000991, I think they aren't going to fix it or made the behaviour intentional for some reason. In that way, is there going to be a deffinitive fix included from the Activiti side in aome new release?

Any suggestion will be very appreciated. Thanks!

M

1 ACCEPTED ANSWER

afaust
Legendary Innovator
Legendary Innovator

Ahh, too bad the script is interpreted and not compiled. It looks like the problem in your case has nothing to do with the setVariable() and/or resultVariable at all. The issue originates from SimpleScriptContext.setAttribute which is only called for variable local variable assignments. The Activiti engine creates a custom script binding linked to the current execution. Whenever a local variable is defined in a script it will store that variable in the execution. The cause may be your use of the "var" keyword. In JavaScript all variables defined via "var" will be initialised with "undefined" at the start of their enclosing scope (script file / function). The statement

var rv = "hello";

actually results in two distinct runtime instructions

var rv;
rv = "hellO";

Please try running your process without the "var" keyword. Note that Activiti will still store all variables in the execution by default.

Another option would be to wrap the listener code in an anonymous function to avoid adding to the implicit global scope

(function(){
   var rv = "hello";
   execution.setVariable("result", rv);
}());

I have only ever used the Alfresco ECM specific script execution listener and this does behave quite a bit different in this context, without requiring any of these shenanigans (even after upgrades from Java 6 to 7 or 8).

View answer in original post

12 REPLIES 12

matutano6
Champ in-the-making
Champ in-the-making

Great explanation and great solution!

Without the "var" keyword, both ways worked (using "resultVariable" parameter and with "setVariable")

Allright, just to clarify: the problem is really related to the JVM behaviour, but it fires at the variable declaration using "var" keyword, not while returning the result. Am I right? This may help other in the future.

Thanks again!

M

afaust
Legendary Innovator
Legendary Innovator

Your understanding is correct. I would want to separate the script engine behaviour from the JVM behaviour. Effectively, Sun/Oracle only licensed and integrated an already existing open source JavaScript engine from Mozilla (Rhino) which runs "on" the JVM but should not be considered part of the JVM. Essentially it is just a reference implementation for JSR-223 that is shipped with the JRE/JDK.

matutano6
Champ in-the-making
Champ in-the-making

Hi again! I now upgraded from JDK 1.7 to JDK 1.8 and found myself with Nashorn and the resurrection of the issue (I'm still using Activiti engine 5.17.0 for production)

The ScriptTasks do work with the precaussion of not using the var keyword neither the "resultVariable" for the implicit result. But now, ScriptExecutionListeners fail no matter what with the following exception:

org.activiti.engine.ActivitiException: couldn't find a variable type that is able to serialize [object global]
    at org.activiti.engine.impl.variable.DefaultVariableTypes.findVariableType(DefaultVariableTypes.java:62)

Is there a way to deal with that? Is there a workarround other than extracting ScriptExecutionListeners into ScriptTasks? I'm evaluating the use of groovy instead of JS too, but it would be very painful for definition's designers.

Thanks!

M