0

I have a javascript file fun.js

function fun1(){
    var arr =['This','is','from','js'];
    return arr;
}

I want to get this array in java array so I used nashorn as-

try{
    ScriptEngine engine= new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(new FileReader("fun.js"));
    Invocable invocable = (Invocable) engine;
    Object obj = (Object)invocable.invokeFunction("fun1");
    System.out.println(obj.toString());
}
catch(Exception e){
    e.printStackTrace();
}

But I am getting this output- [object Array]

How can I get this output as java array?

6
  • 1
    eval() is one of the worst things you could ever do in any language. Commented Mar 25, 2018 at 6:01
  • Did you try looping through the array and printing out the contents? Commented Mar 25, 2018 at 6:04
  • Should type cast to Object[] and then use for loop. Commented Mar 25, 2018 at 6:05
  • @Prashant It gives error as -- java.lang.ClassCastException: jdk.nashorn.api.scripting.ScriptObjectMirror cannot be cast to [Ljava.lang.Object; Commented Mar 25, 2018 at 7:26
  • what is the content of your file fun.js. Also please show the code of method fun1 Commented Mar 25, 2018 at 11:56

5 Answers 5

2
public static void main(String[] args) throws JSONException, FileNotFoundException, ScriptException, NoSuchMethodException {

        ScriptEngine engine= new ScriptEngineManager().getEngineByName("nashorn");

        engine.eval(new FileReader("C:\\Users\\Niku\\eclipse-workspace\\java_sample\\src\\test.js"));

        Invocable invocable = (Invocable) engine;
        Object obj = (Object)invocable.invokeFunction("fun1");
        Gson gson = new Gson();
        String k = gson.toJson(obj);
        JSONObject o = new JSONObject(k);
        System.out.println(o.getString("0"));
        System.out.println(o.getString("1"));
        System.out.println(o.getString("2"));
        System.out.println(o.getString("3"));

        Iterator x = o.keys();
        JSONArray jsonArray = new JSONArray();
        ArrayList<String> ar = new ArrayList<String>();
        while (x.hasNext()){
            String key = (String) x.next();
            ar.add(o.get(key).toString());
            jsonArray.put(o.get(key));
        }

        System.out.println(ar);
}

Iterating through the JsonObject can get you each element which can be added to another array to be used.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use methods of Nashorn specific extension object "Java" to convert between JavaScript and Java arrays.

See also: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-java_to

Simple Example that invokes Java.to from Java code:

import javax.script.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ScriptEngine e = new ScriptEngineManager().getEngineByName("nashorn");
        e.eval("function fun1() { return ['this', 'is', 'from', 'js']; }");
        Invocable invocable = (Invocable)e;
        Object obj = (Object)invocable.invokeFunction("fun1");
        // get "Java" api object
        Object Java = e.get("Java");
        // invoke Java.to function to convert JS array to Java String array
        String[] arr = (String[])invocable.invokeMethod(
            Java, "to", obj, "java.lang.String[]");
        // access String array
        for (String s : arr) { System.out.println(s); }
    }
}

Comments

0

The invokeFunction returns an instance of JSObject [jdk.nashorn.api.scripting.JSObject]

You could assign the response to a JSObject and then iterate over the values -

JSObject jsObject = null;
try {
    jsObject = (JSObject) invocable.invokeFunction("fun1");
    for (Object object : jsObject.values()) {
        System.out.println(object);
    }
} catch (NoSuchMethodException e) {
    ...
}

1 Comment

Make sure that the import for the JSObject is jdk.nashorn.api.scripting.JSObject
0

I have tried recreating the scenario in java alone and was able to print the contents.

public class test {
    public static void main(String[] args) {
        String[] a = {"This","is","from","js"};
        Object obj = (Object) a;
        String stringArray = Arrays.deepToString((Object[]) obj);
        System.out.println(stringArray);
        String [] b =  stringArray.replaceAll("[\\[\\]]", "").split(",");
        System.out.println(b[0]);   
    }
}

1 Comment

But in this case it gives this error-- java.lang.ClassCastException: jdk.nashorn.api.scripting.ScriptObjectMirror cannot be cast to [Ljava.lang.Object;
0

The output what you'll get in Java will be in JsonArray format. So you can pass your input content in jsonArray and iterate over that JsonArray.

you can use jettison-1.3.jar as JSONAray library.

Here's what you can try.

String[] outputStr = new String[jsonArray.length()];
try {
    JSONArray jsonArray = new JSONArray(invocable.invokeFunction("fun1"));
    for (int i = 0; i < jsonArray.length(); i++) {
        outputStr[i] = jsonArray.getString(i);
    }
} catch(JSONException ex) {
    ex.printStackTrace();
}

For using org.json.simple.JSONArray import, you can use the following code

    String[] outputStr = new String[jsonArray.length()];
    try{
        JSONParser parser = new JSONParser();
        JSONArray jsonArray = (JSONArray) parser.parse(invocable.invokeFunction("fun1");

        for (int i = 0; i < jsonArray.size(); i++) {
            outputStr[i] = (String) jsonArray.get(i);
        }
    } catch(JSONException ex) {
        ex.printStackTrace();
    }

5 Comments

Can I use this code in java program directly.I tried this with jettison-1.3.jar but it gives error .I import following-- import org.json.simple.JSONObject; import org.json.simple.JSONArray;
with jettison jar, your import will be org.codehaus.jettison.json.JSONArray. Yes you can use this code directly in Java program
It gives this error when using jettison.jar- no suitable constructor found for JSONArray(Object) constructor JSONArray.JSONArray(JSONTokener) is not applicable (argument mismatch; Object cannot be converted to JSONTokener) and 3 more like this....
While using 2nd code I got follwing 2 error no suitable method found for parse(Object) JSONArray jsonArray = (JSONArray) parser.parse(invocable.invokeFunction("fun1")); method JSONParser.parse(String) is not applicable (argument mismatch; Object cannot be converted to String) error: cannot find symbol method length()
Thanks for your effort madam I got the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.