One of the awesome things of having a big open source community is that it makes Activiti run on platforms and configuration which we don’t have in our automated QA environment. Regardless of how many people/time/money you have, there’s always going to be a funny configuration that makes the software behave just differently.
So one of the issues discovered and reported by Brian Showers in the Activiti forum, is that the test suite doesn’t run green on JDK 1.7.0._17. And indeed, my dev machine didn’t have the latest JDK installed nor had the QA at the time of writing.
So what is the problem? Well, in Activiti when using a scriptTask, you can write something like
<scriptTask id="myScript" scriptFormat="JavaScript"> <script><![CDATA[ var sum = a + b; ]]></script> </scriptTask>
The variable sum will be automatically saved as a process variable (unless you set the property “activiti:autoStoreVariables=’false'” on the scriptTask). This has worked since whatever version of Activiti we introduced scripting. So it has worked for JDK 5, 6 and until recently 7. But on the latest JDK, at the time of writing 1.7.0_17, it doesn’t run. It throws an exception:
org.activiti.engine.ActivitiException: couldn’t find a variable type that is able to serialize sun.org.mozilla.javascript.internal.Undefined@7216df
at org.activiti.engine.impl.variable.DefaultVariableTypes.findVariableType(DefaultVariableTypes.java:62)
at org.activiti.engine.impl.persistence.entity.VariableScopeImpl.createVariableInstance(VariableScopeImpl.java:359)
at org.activiti.engine.impl.persistence.entity.VariableScopeImpl.createVariableLocal(VariableScopeImpl.java:292)
at org.activiti.engine.impl.persistence.entity.VariableScopeImpl.createVariableLocal(VariableScopeImpl.java:279)
at org.activiti.engine.impl.persistence.entity.VariableScopeImpl.setVariable(VariableScopeImpl.java:254)
at org.activiti.engine.impl.persistence.entity.VariableScopeImpl.setVariable(VariableScopeImpl.java:237)
at org.activiti.engine.impl.scripting.ScriptBindings.put(ScriptBindings.java:83)
at javax.script.SimpleScriptContext.setAttribute(SimpleScriptContext.java:228)
at com.sun.script.javascript.ExternalScriptable.put(ExternalScriptable.java:182)
at sun.org.mozilla.javascript.internal.ScriptableObject.defineProperty(ScriptableObject.java:1394)
at sun.org.mozilla.javascript.internal.ScriptRuntime.initScript(ScriptRuntime.java:3239)
at sun.org.mozilla.javascript.internal.Interpreter.initFrame(Interpreter.java:2695)
at sun.org.mozilla.javascript.internal.Interpreter.interpret(Interpreter.java:844)
at sun.org.mozilla.javascript.internal.InterpretedFunction.call(InterpretedFunction.java:162)
at sun.org.mozilla.javascript.internal.ContextFactory.doTopCall(ContextFactory.java:429)
at com.sun.script.javascript.RhinoScriptEngine$1.superDoTopCall(RhinoScriptEngine.java:116)
at com.sun.script.javascript.RhinoScriptEngine$1.doTopCall(RhinoScriptEngine.java:109)
at sun.org.mozilla.javascript.internal.ScriptRuntime.doTopCall(ScriptRuntime.java:3161)
at sun.org.mozilla.javascript.internal.InterpretedFunction.exec(InterpretedFunction.java:173)
at sun.org.mozilla.javascript.internal.Context.evaluateReader(Context.java:1159)
…
So it seems that in the latest JDK 7 version, somehow the class that is used to represent a scripting variable in the JDK isn’t Serializable anymore. However, if you switch your script to
<scriptTask id="myScript" scriptFormat="JavaScript"> <script><![CDATA[ var sum = a + b; execution.setVariable("sum", sum); ]]></script> </scriptTask>
It just works. When I debugged, an object of the class ‘Double’ was passed instead of ‘Undefined’ in the first example. So when calling a Java object from a script, some auto-coercion/conversion is happening … which is not happening in the first example. Unfortunately all the classes involved are internal classes (eg sun.javascript.xxxxx) so we can’t just force the conversion somehow as this would break on some systems.
So what options do we have
So the current thinking is that we wait a bit until next release. In the mean time, I’l try to figure out how to report a JDK bug.
People that are depending on the auto storage of variable will have to use the workaround with execution.setVariable(name, value); for the moment. If anybody has any input regarding this issue, please let us know!
I ran into this issue with JDK 1.6.0_43, too. But the fix with workround is fine.
@Ingo: thanks. It seems that is will be a ‘bugfix’ on the newest JDK releases.
Didn’t get an answer to my JDK bug report either :-/.
@Joram – do you have any JDK bug numbers for this?
Yeah, I got this mail after I submitted the bug:
Dear Java Developer,
Thank you for reporting this issue.
We have determined that this report is a new bug and entered the bug into our internal bug tracking system under Bug Id: 9000991.
You can monitor this bug on the Java Bug Database at
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=9000991.
It may take a day or two before your bug shows up in this external database.
Regards,
Java Developer Support
But that bug doesn’t seem to exist anymore now …. wtf?
I think there is also a problem with date type, the following script throws an exception. I will try with groovy language to see if I can achieve my purpouse.
d = new Date();
execution.setVariable("myVar", d)
Couldn’t serialize value ‘sun.org.mozilla.javascript.internal.NativeDate@67e236’ in variable ‘d’
Is it a bug? Or I am doing something wrong??
@Javi: did you try be adding java.util in front of Date?
Im sure that Groovy would work out of the box.
Any update about this? I’m working with JDK 1.7.0.45 and I still have the same problem..
Any advance?
No, this ‘bug’ still exists on the latest releases. I put ‘bug’ between quotes because I believe it’s a fix they added and it won’t go away.
The workaround is as suggested in the past above, add an explicit ‘execution.setVariable’ call in the script and it should be fine.
I am facing a typical problem with Script task. While trying to store boolean value with following code,
execution.setVariable(“abc”, Boolean.TRUE);
execution.setVariable(“bbc”, false);
in variable table its storing as follows. Type storing properly but, text_ not storing.
mysql> select name_, text_, type_ from act_ru_variable where proc_inst_id_ = ‘297505’;
+——-+——-+———+
| name_ | text_ | type_ |
+——-+——-+———+
| abc | NULL | boolean |
| bbc | NULL | boolean |
+——-+——-+———+
2 rows in set (0.00 sec)
How to store boolean variables in execution using groovy script?
Any help will be appreciated.
@Swamy: this is more a question for the user forum (http://forums.activiti.org/).
The boolean variable type uses the long column, not the text_ column.
So I am currently having an issue with this. I updated to 12.1 but now processes that started before the update won’t work anymore due to this (Unknown property used in expression).
Is there any way to fix it with a db script maybe?
I solved it by creating a method to set the variables in runtimeService if they are not present