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