一个典型的JSR-223脚本会以一系列类似这样的代理导入开始(选择 JavaScript+Nashorn 作为示例):
// "import" classes and static methods
var Foo = Java.type("my.package.Foo"); // application classes require Java.type() use
var bar = Foo.bar; // static method
var Logger = java.util.logging.Logger; // system classes can be accessed directly
var sin = java.lang.Math.sin; // the same for static methods
// use them
var foo = new Foo();
print(bar());
var log = Logger.getLogger("foo");
print(sin(42));
我想通过模拟脚本的类似导入功能来摆脱这些代理。这意味着,我希望我的 Java 代码预先创建了全局对象(如上例中的、Foo
和) 。这应该会自动为多个脚本提供一组通用的导入。bar
Logger
sin
我找到了两种使用 Nashorn 的方法:
方法一eval()
:在主脚本之前生成一个脚本前奏。这实际上是上面示例代码的前半部分。
方法 2:从 ScriptEngine 获取类和方法引用,缓存它们并用于后续脚本调用:
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine nashorn = sem.getEngineByName("nashorn");
Object fooClass = nashorn.eval("Java.type('my.package.Foo')"); // instance of jdk.internal.dynalink.beans.StaticClass
Object loggerClass = nashorn.eval("java.util.logging.Logger"); // the same
Object barFunction = nashorn.eval("Java.type('my.package.Foo').bar"); // instance of jdk.internal.dynalink.beans.SimpleDynamicMethod
Object sinFunction = nashorn.eval("java.lang.Math.sin"); // the same
ScriptEngine nashorn1 = sem.getEngineByName("nashorn");
nashorn1.put("Foo", fooClass);
nashorn1.put("bar", barFunction);
nashorn1.put("Logger", loggerClass);
nashorn1.put("sin", sinFunction);
nashorn1.eval("var foo = new Foo(); bar(); var log = Logger.getLogger('foo'); print(sin(42));");
显然,这些方法都不适用于任何其他 JSR-223 引擎。有没有办法以可移植的方式实现相同的功能?