我们希望将Jython解释器集成到基于Eclipse RCP的解决方案中,我们需要从那里访问OSGi包(例如来自Activator.getContext().getBundles()
的所有内容)。
我怎样才能将这些包传递给Jython PythonInterpreter
对象python.path
属性,所以我可以从Jython代码中导入这些类?
(当我尝试导入包时,我收到类似的错误消息:
from org.eclipse.chemclipse.msd.converter.chromatogram import ChromatogramConverterMSD
)
ImportError:无法导入名称ChromatogramConverterMSD
答案 0 :(得分:0)
我在这个问题上工作了好几天后找到了解决办法。
首先,我们需要ClassLoader
,如果需要,可以加载OSGi包:
public class JythonClassLoader extends ClassLoader {
private final Bundle bundle;
public JythonClassLoader(ClassLoader parent, Bundle bundle) {
super(parent);
this.bundle = bundle;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// System.out.println("findClass " + name);
try {
return super.findClass(name);
} catch(ClassNotFoundException e) {
Class<?> loadClass = bundle.loadClass(name);
if(loadClass != null)
return loadClass;
throw e;
}
}}
然后PythonInterpreter
需要知道这个ClassLoader
。最好的方法是先为PythonInterpreter
设置环境。以下课程完成了这项工作:
public class JythonEnvironment {
private final Bundle bundle;
public JythonEnvironment(Bundle bundle) {
this.bundle = bundle;
}
public PySystemState getPySystemState() {
Properties properties = new Properties();
String jythonPath = net.openchrom.thirdpartylibraries.jython.Activator.getJythonPath();
properties.setProperty("python.home", jythonPath);
properties.setProperty("python.cachedir.skip", "true");
Properties systemProperties = System.getProperties();
PySystemState.initialize(systemProperties, properties, new String[]{""});
PySystemState pySystemState = new PySystemState();
JythonClassLoader classLoader = new JythonClassLoader(getClass().getClassLoader(), bundle);
pySystemState.setClassLoader(classLoader);
return pySystemState;
}
public PythonInterpreter getInterpreter() {
return new PythonInterpreter(null, getPySystemState());
}
public PythonInterpreter getInterpreter(OutputStream outStream, OutputStream errStream) {
PythonInterpreter interpreter = new PythonInterpreter(null, getPySystemState());
interpreter.setErr(outStream);
interpreter.setOut(errStream);
return interpreter;
}}
JythonEnvironment
类需要知道捆绑包。如果可以通过Activator
收到最好的那个。
JythonEnvironment environment = new JythonEnvironment(Activator.getDefault().getBundle());
希望这个答案可以节省时间,如果其他人需要将Jython集成到基于Eclipse RCP的解决方案中。