Message10872

Author jjdelcerro
Recipients jjdelcerro
Date 2016-07-02.17:47:26
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1467481648.67.0.737202507721.issue2507@psf.upfronthosting.co.za>
In-reply-to
Content
I using "javax.script.ScriptEngine" (jsr223) to access python scripts.
I set in the context a writer (setWriter and setErrorWriter) to get the 
stdout and stderr of the python script.
When call the funcion of the script from a thread don't' use the writer set in the context. 

I patch the invokeFunction method of PyScriptEngine setting in, out, err and locals and creating a ThreadState and passing it as the first argument of __call__.

    public Object invokeFunction(String name, Object... args) throws ScriptException,
            NoSuchMethodException {
        try {
            PyObject function = interp.get(name);
            if (function == null) {
                throw new NoSuchMethodException(name);
            }
            interp.setIn(context.getReader());
            interp.setOut(context.getWriter());
            interp.setErr(context.getErrorWriter());
            interp.setLocals(new PyScriptEngineScope(this, context));
            ThreadState state = new ThreadState(this.interp.getSystemState());
            PyObject result;
            if(args != null) {
                result = function.__call__(state,Py.javas2pys(args));
            } else {
                result = function.__call__(state);
            }
            return result.__tojava__(Object.class);
        } catch (PyException pye) {
            throw scriptException(pye);
        }
    }

This solves my problem but do not know if it's right.
If correct, it might have to do the same in method InvokeMethod.

The code to reproduce the problem is:

package org.python.jsr223;

import java.io.IOException;
import java.io.Writer;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class TestInvokeFunction {

    public static final String code = "print \"module\"\n"
            + "\n"
            + "def main(*args):\n"
            + "    print \"main\"\n";

    public static class Output extends Writer {
        private final String label;

        public Output(String label) {
            this.label = label;
        }
        @Override
        public void write(char[] cbuf, int off, int len) throws IOException {
            String s = new String(cbuf,off,len);
            System.out.println(label + " " + s);
        }

        @Override
        public void flush() throws IOException {
        }

        @Override
        public void close() throws IOException {
        }
        
    }
    
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("python");
        ScriptContext context = engine.getContext();
        context.setWriter(new Output("[STDOUT]"));
        context.setErrorWriter(new Output("[STDERR]"));
        
        Compilable compilable = (Compilable) engine;
        CompiledScript compiledCode = compilable.compile(code);
        compiledCode.eval();
     
        final Invocable invocable = (Invocable) engine;
        // The output of this is ok
        Object r = invocable.invokeFunction("main", (Object[]) null);

        Runnable process = new Runnable() {
            @Override
            public void run() {
                try {
                    // The output of this is not get with the "Output" class.
                    Object r = invocable.invokeFunction("main", (Object[]) null);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        Thread thread = new Thread(process);
        thread.setDaemon(false);
        thread.start();
    }

}


And the output is:

[STDOUT] module
[STDOUT] 

[STDOUT] main
[STDOUT] 

main

Sorry for my english.
Joaquin
History
Date User Action Args
2016-07-02 17:47:28jjdelcerrosetrecipients: + jjdelcerro
2016-07-02 17:47:28jjdelcerrosetmessageid: <1467481648.67.0.737202507721.issue2507@psf.upfronthosting.co.za>
2016-07-02 17:47:28jjdelcerrolinkissue2507 messages
2016-07-02 17:47:26jjdelcerrocreate