Search code examples
javajava-8nashorn

Java 8 Nashorn - capturing engine.eval("print('hello world')) into String object?


Is there a way to capture the result of print('hello world') inside Nashorn and place it in a String object.

I have tried this:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, true);
System.setOut(ps);

String result = (String)engine.eval("print('hello world')");

if (result != null) {
    System.out.println(result);
} else {
    System.out.println(baos.toString());
}

When engine evaluates this javascript it just prints to stdout so I figured I just redirect stdout to my own OutputStream and then convert it to String, but it doesn't work.

Any thoughts?


Solution

  • You are setting the System.out stream after you have created your engine so it’s very likely that the engine’s context has already recorded the value of System.out/System.err at construction time.

    Therefore you still see the output of the script on the console. Even worse, you don’t see the output of your own later-on System.out.println anymore as you have redirected System.out to your ByteArrayOutputStream.

    So don’t modify System.out, instead change the output in the context of your scripting engine engine.getContext().setWriter(stringWriter).

    Complete code:

    StringWriter sw=new StringWriter();
    engine.getContext().setWriter(sw);
    String result = (String)engine.eval("print('hello world')");
    System.out.println("Result returned by eval(): "+result);
    System.out.println("Captured output: "+sw);