3

I'm trying to use javax.script.ScriptEngine to eval() some JS scripts. How can I know if the result after eval() which is of type Object is an array? And if so, how can I cast it?

Right now, to know if the object is of type Number or of type String i use instanceof. And when the result of the script is an array, if I print with System.out.println() the object returned it simply prints [object Array].

4 Answers 4

2

As you noticed, it's not java array but a javascript array, if you print the class of the return object, you probably will find it's "ScriptObjectMirror". I have a work around for this which is toString the array in another your script variable, then get the value of that (see below example). I believe there is a better way to resolve this array issue, waiting the good answer too.

engine.eval("var fruits = [\"Banana\", \"Orange\", \"Apple\", \"Mango\"]; var d = fruits.toString();");
System.out.println(engine.get("fruits").getClass());
System.out.println(engine.get("d").getClass());
System.out.println(engine.get("d"));
Sign up to request clarification or add additional context in comments.

Comments

2

In my case modifying the script to make it return list does the trick:

private String arrayToList() {
    if (javascript.startsWith("[") && javascript.endsWith("]"))
        javascript = "java.util.Arrays.asList(" + javascript + ")";
    return javascript;
}

But of course it handles only the case where array results from using brackets, for example:

["entry1", "entry2", settings.getMainUserEmail(), loginEmail]

Anyway the bottom line is that you need to return a List instead of array. Then you can also use instanceof.

Comments

1

How can I know if the result after eval() which is of type Object is an array?

Use instanceof:

if(result instanceof Object[]){
    //your code
}

And if so, how can I cast it?

if(result instanceof Object[]){
    Object[] array = (Object[])result;
    for(Object o : array) {
    //your code
    }
}    

1 Comment

That didn't work. The instanceof in the if statement returns false.
0
final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
scriptEngine.eval("count = ['one', 'two', 'three'];");
scriptEngine.eval("className = count.constructor.name;");

final String className =  (String) scriptEngine.get("className");

switch(className) {

case "Array":
    scriptEngine.eval("json= JSON.stringify(count);");
    final String json =  (String) scriptEngine.get("json");

    final ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    final String[] readValue = mapper.readValue(json, String[].class);
    break;

case "Number":
    ...
}

Comments

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.