cancel
Showing results for 
Search instead for 
Did you mean: 

Attempting to store JavaScript objects to process variables fails

andrewlecouteur
Champ in-the-making
Champ in-the-making
The following script task fails:
<javascript>
var structure = {
fred: 123,
bill: ['x', 'y', 'z'],
eric: { smoo: 'froob'}
};
execution.setVariable("STUFF",structure);
</javascript>

It fails because findVariableType() in DefaultVariableTypes.java cannot locate an appropriate type for storage.
The returned value is a sun.org.mozilla.javascript.internal.NativeObject which seems to be opaque. The original Rhino type was org.mozilla.javascript.NativeObject which is Serializable and would therefore be handled automatically as a SerializableType in the Activiti engine.

Is there a simple way to allow this to work?  It seems like a fairly fundamental requirement so I assume someone must have investigated this.

Thanks,
Andy
5 REPLIES 5

pkonyves
Champ in-the-making
Champ in-the-making
Hi, try creating a serializable object. Search for 'serializable' on this page, maybe you can get some ideas: http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html

I really want to implement this in a way that leaves the scripts "looking" like JavaScript.  One solution is to use
<javascript>
execution.setVariable("STUFF", JSON.stringify(structure));
</javascript>
but this seems rather arbitrary.  Surely there is some way that the code shown above can be made to work?

trademak
Star Contributor
Star Contributor
JSON.stringify would a fine approach to store the variable as a JSON String in the database. The other approach is to use a Serializable Java type instead like mentioned by pkonyves. Don't see any other approach actually.

Best regards,

andrewlecouteur
Champ in-the-making
Champ in-the-making
I have now implemented a method whereby JavaScript objects can be stored and retrieved directly to/from process variables.  This involves the use of private code in the sun.org.mozilla.javascript.internal namespace but this interface is very unlikely to change and, in any case, there is no alternative if you are using the JavaScript engine in rt.jar.  It could be made more legitimate by using the original js.jar from Mozilla but I am unsure if this can be substituted without any issues in the rest of the Activiti code-base.  I suspect that it can.

JavaScript objects and arrays are serialised to JSON for storage.

This code will, of course, need to be revisited when we eventually move to Nashorn but that isn't a major concern for our purpose.
I guess that the use of a private API will mean that this code will never be suitable for inclusion in the Activiti project but it can be done and it isn't that hard once you find the correct documentation.  The Oracle documentation is quite useless but the original documentation for org.mozilla.javascript is very helpful. 

If anyone wants a copy of my code then please ask.  If there is enough interest I will put it somewhere publicly accessible.

jbarrez
Star Contributor
Star Contributor
Thanks for writing that up. The problem is indeed that the JS engine inside of the JVM is

1) sucky at many places
2) depending on the vendor

Smiley Sad