Message10872
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 |
|
Date |
User |
Action |
Args |
2016-07-02 17:47:28 | jjdelcerro | set | recipients:
+ jjdelcerro |
2016-07-02 17:47:28 | jjdelcerro | set | messageid: <1467481648.67.0.737202507721.issue2507@psf.upfronthosting.co.za> |
2016-07-02 17:47:28 | jjdelcerro | link | issue2507 messages |
2016-07-02 17:47:26 | jjdelcerro | create | |
|