使来自其他包的 Eclipse RCP 包在 JavaScript 中可用

Make Eclipse RCP package from other bundle available in JavaScript

我有一个 Eclipse RCP 应用程序,可以在 Nashorn JVM 上评估 JavaScript 文本。

Bundle A实现了对JS的求值。

JS 脚本引用了 Bundle B 中的 classes,例如。枚举 class。但是 Bundle A 不知道这个 Bundle B。Bundle B 通过读取外部 jar 文件动态加载 classes。

现在,当我使用 importPackage 或 Java.type 时,我得到一个 ClassNotFoundException。

在 Bundle A 中,我可以从 JAR 中检索 Bundle B 中的对象。通过它的 classloader,我还可以从 JAR 访问其他 classes。

getBundleBObj().getClass().getClassLoader().loadClass( "my.ClassEnum" );

这就成功了。
我能以某种方式使用它,使包 'my.*'(来自 Bundle B)在 JS 中可用吗?

如果您有一个 java.lang.Class 实例,您可以将其作为全局变量公开给脚本并在其上使用 "static" 属性。

在Java中:

// Class yourClassObject = ...

// expose Class object as variable to your script
// "engine" is nashorn engine instance

engine.put("MyClass", yourClassObject);

在Java脚本中:

var M = MyClass.static;
var obj = new M(); // create object
M.func(); // call static method

最干净的方法是让 Bundle A 提供一个 API 或扩展点供 Bundle B 使用,以便将其类加载器或一些特定的 类 添加到 Nashorn 引擎在 Bundle A 中实例化。

另一种方法是查看允许在包之间获取类加载器 "leaking" 的 Eclipse-BuddyPolicy": https://wiki.eclipse.org/Context_Class_Loader_Enhancements#Buddy_Class_Loading 。但这恰好是针对 OSGi 的黑客攻击,它使维护变得更加困难并且代码不会可移植到 Equinox 以外的其他 OSGi 容器。