javastreamjavax.script

How to write to Nashorn error stream?


I use Nashorn scripts from a Java application. Java sets the context (including errorWriter) and everything just works fine... BUT i haven't found the way to write to the error Stream from the nashorn script. Does anyone know ?

I tried to throw an error but it outputs in the scriptException, not in the error output Stream.

Thanks for any idea.


Solution

  • It looks like there is no built in function to write to stderr, like there is one to write to stdout (print).

    But, you can set an attribute in the ScriptContext that has a function to write to it's error writer.

    ScriptEngine se = ...;
    
    ScriptContext sc = se.getContext();
    sc.setAttribute("stderr", // name is 'stderr'
        (Consumer<String>) str -> { // Object is a Consumer<String> 
            try {
                Writer err = sc.getErrorWriter();
                err.write(str);
                err.flush();
            } catch (Exception e) {
                throw new Error(e);
            }
        },
        ScriptContext.ENGINE_SCOPE // i.e. don't share with other engines
    );
    

    The reason to do it this way, instead of binding the error writer object directly, is that you can still change the error writer later, and it will still work.

    Afterwards you could do this:

    sc.setErrorWriter(new PrintWriter(new OutputStream() {          
        @Override
        public void write(int b) throws IOException {
            System.err.write(b);                
        }
    }));
    

    Which will write all the errors to the Java stderr (which is not the default btw).

    Then from javascript you can do:

    var error = function(message) { // A nice wrapper function
        stderr.accept(message); // 'accept', since we passed a `Consumer<...>`
    };
    
    error('error'); // Will now print to Java's stderr