即时为Jython Interpreter传递OSGi包

时间:2015-06-23 11:42:24

标签: java osgi jython

我们希望将Jython解释器集成到基于Eclipse RCP的解决方案中,我们需要从那里访问OSGi包(例如来自Activator.getContext().getBundles()的所有内容)。

我怎样才能将这些包传递给Jython PythonInterpreter对象python.path属性,所以我可以从Jython代码中导入这些类?

(当我尝试导入包时,我收到类似的错误消息: from org.eclipse.chemclipse.msd.converter.chromatogram import ChromatogramConverterMSD

  

ImportError:无法导入名称ChromatogramConverterMSD

1 个答案:

答案 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的解决方案中。