From c4a1c1412da246071af6dcf5a9969e1b79f9fcbc Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Thu, 30 Jun 2016 09:47:20 +0000 Subject: [PATCH] SSDM-3745: Jython27: Execute everything with the right context class loader otherwise python xml module wouldn't work SVN: 36769 --- .../cisd/common/jython/v27/Evaluator27.java | 2 +- .../cisd/common/jython/v27/JythonUtils.java | 37 +++++++++++++++- .../jython/v27/PythonInterpreter27.java | 42 ++++++++++++++++++- 3 files changed, 77 insertions(+), 4 deletions(-) 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 8d527f6971c..9a9c6f05cb0 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 19a75bf2ba9..f7fbf811367 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 62f0a229873..e6b85e5c9a8 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 { -- GitLab