diff --git a/common/source/java/ch/systemsx/cisd/common/jython/v27/Evaluator27.java b/common/source/java/ch/systemsx/cisd/common/jython/v27/Evaluator27.java index 8d527f6971ce9b07ca5a360dc60b67fdf6f1a2f5..9a9c6f05cb0395aca4f7cfe237311c69fdb4c73a 100644 --- a/common/source/java/ch/systemsx/cisd/common/jython/v27/Evaluator27.java +++ b/common/source/java/ch/systemsx/cisd/common/jython/v27/Evaluator27.java @@ -190,7 +190,7 @@ public final class Evaluator27 implements IJythonEvaluator { pyArgs[i] = translateToPython(args[i]); } - PyObject result = func.__call__(pyArgs); + PyObject result = JythonUtils.invokeFunction(func, pyArgs); return translateToJava(result); } catch (PyException ex) { diff --git a/common/source/java/ch/systemsx/cisd/common/jython/v27/JythonUtils.java b/common/source/java/ch/systemsx/cisd/common/jython/v27/JythonUtils.java index 19a75bf2ba9f40e2e0063abef9b7201a80b5e1ee..f7fbf81136773e8fe2033ba50f16e480e50c6385 100644 --- a/common/source/java/ch/systemsx/cisd/common/jython/v27/JythonUtils.java +++ b/common/source/java/ch/systemsx/cisd/common/jython/v27/JythonUtils.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.common.jython.v27; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.Callable; import org.python27.core.Py; import org.python27.core.PyDictionary; @@ -25,6 +26,8 @@ import org.python27.core.PyFunction; import org.python27.core.PyObject; import org.python27.core.PySequenceList; +import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; + /** * Jython utility methods. * @@ -76,7 +79,39 @@ class JythonUtils { pyArgs[i] = Py.java2py(args[i]); } - return function.__call__(pyArgs); + return invokeFunction(function, pyArgs); + } + + static PyObject invokeFunction(final PyFunction function, final PyObject[] pyArgs) + { + return executeWithContextClassLoader(function, new Callable<PyObject>() + { + @Override + public PyObject call() throws Exception + { + return function.__call__(pyArgs); + } + }); + } + + static final <V> V executeWithContextClassLoader(Object object, Callable<V> action) + { + Thread thread = Thread.currentThread(); + ClassLoader originalContextClassLoader = thread.getContextClassLoader(); + try + { + thread.setContextClassLoader(object.getClass().getClassLoader()); + try + { + return action.call(); + } catch (Exception ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + } finally + { + thread.setContextClassLoader(originalContextClassLoader); + } } } diff --git a/common/source/java/ch/systemsx/cisd/common/jython/v27/PythonInterpreter27.java b/common/source/java/ch/systemsx/cisd/common/jython/v27/PythonInterpreter27.java index 62f0a229873153621d36676c479507624540b9f9..e6b85e5c9a87bd6b3d34cdcb7ae1ed4d61d77394 100644 --- a/common/source/java/ch/systemsx/cisd/common/jython/v27/PythonInterpreter27.java +++ b/common/source/java/ch/systemsx/cisd/common/jython/v27/PythonInterpreter27.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.common.jython.v27; +import java.util.concurrent.Callable; + import org.apache.log4j.Logger; import org.python27.core.CompileMode; import org.python27.core.Py; @@ -131,7 +133,35 @@ class PythonInterpreter27 extends org.python27.util.PythonInterpreter return new PythonInterpreter27(); } - public void exec(String data, String filename) + @Override + public void exec(final String s) + { + JythonUtils.executeWithContextClassLoader(this, new Callable<Void>() + { + @Override + public Void call() throws Exception + { + PythonInterpreter27.super.exec(s); + return null; + } + }); + } + + @Override + public void exec(final PyObject code) + { + JythonUtils.executeWithContextClassLoader(this, new Callable<Void>() + { + @Override + public Void call() throws Exception + { + PythonInterpreter27.super.exec(code); + return null; + } + }); + } + + public void exec(final String data, final String filename) { String[] pythonPath = ch.systemsx.cisd.common.jython.JythonUtils.getScriptDirectoryPythonPath(filename); @@ -143,7 +173,15 @@ class PythonInterpreter27 extends org.python27.util.PythonInterpreter setSystemState(); - Py.exec(Py.compile_flags(data, filename, CompileMode.exec, cflags), getLocals(), null); + JythonUtils.executeWithContextClassLoader(this, new Callable<Void>() + { + @Override + public Void call() throws Exception + { + Py.exec(Py.compile_flags(data, filename, CompileMode.exec, cflags), getLocals(), null); + return null; + } + }); Py.flushLine(); } finally {