Issue2507
Created on 2016-07-02.17:47:28 by jjdelcerro, last changed 2018-03-05.17:25:51 by jeff.allen.
Messages | |||
---|---|---|---|
msg10872 (view) | Author: Joaquin Jose del Cerro Murciano (jjdelcerro) | Date: 2016-07-02.17:47:26 | |
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 |
|||
msg11735 (view) | Author: Jeff Allen (jeff.allen) | Date: 2018-03-03.14:07:21 | |
Nicely-made demo program. Something in common with where #2513 discussion ended up. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2018-03-05 17:25:51 | jeff.allen | set | keywords: + thread-interpreter context |
2018-03-03 14:07:21 | jeff.allen | set | priority: normal nosy: + jeff.allen messages: + msg11735 milestone: Jython 2.7.2 -> |
2016-09-06 05:19:23 | zyasoft | set | milestone: Jython 2.7.1 -> Jython 2.7.2 |
2016-07-02 17:47:28 | jjdelcerro | create |
Supported by Python Software Foundation,
Powered by Roundup