This question was asked ages ago, but the answers still seemed correct. In case it's of interest to anyone else trying to pass complex objects between Java and Javascript, I wanted to present my solution.
I wrote a script that converts the NativeObject to (in-memory) JSON objects (actually I use MongoDB's BSON-based objects, but you should just be able to substitute 1-1 for JSONArray and JSONObject in the sample code below).
So for example, say I have a (user) script "create_object_script", which "returns" some object or array of interest, then I can convert it into JSON (ie a list of hashmaps) as follows:
Object returnVal = engine.eval(create_object_script);
engine.put("output", returnVal);
BasicDBObject objFactory = new BasicDBObject(); // (or JSON equivalent)
BasicDBList listFactory = new BasicDBList(); // (or JSON equivalent)
BasicDBList outList = new BasicDBList(); // (or JSON equivalent)
engine.put("objFactory", objFactory);
engine.put("listFactory", listFactory);
engine.put("outList", outList);
engine.eval(parsing_script); // (described below)
// "outList" is now populated with (in-memory) JSON representations of "returnVal"
Obviously if you have control over the "create_object_script" script you can do this in a single step; my scripts are user-generated so hiding away this complexity is necessary - the users just write scripts where the "return value" is the final line.
I gisted the "parsing_script" here to keep the length of this post down.
Functionally this works very nicely; I haven't developed in JS much so it's possible there are more efficient ways of doing this. (Note I always need my results in a list, if you don't then you could pass in a BasicDBObject "outObj" and write to that instead in the singleton case).
Hope this helps someone who finds themselves in my situation at 1am last night!