1

我对将 ScriptEngine 合并到我的代码库中感到非常兴奋,并计划使用它从持久化脚本中动态构建接口实现。

我正在为将脚本数据转换为 Java 接口实例的一般实现编写 JUnit 测试用例。我似乎发现您不需要在脚本中实际实现整个接口,就可以将其视为Invocable.getInterface(Class<?>)该接口的对象。根据文档,getInterface我认为如果没有给出完整的实现,我可以指望它返回 null:

Returns:
An instance of requested interface - null if the requested interface is unavailable, 
i. e. if compiled functions in the ScriptEngine cannot be found matching the ones in the requested interface.  

使用Class<?>对象并调用isInstance(Object)结果Invocable.getInterface(Class<?>)似乎总是返回 true。我猜想将动态类型化脚本语言实现映射到静态类型化 Java 接口存在概念上的挑战。但是,如果您尝试在此对象上调用任何未实现的方法,则会出现问题,您会得到一个NoSuchMethodException.

以下是一些有助于说明的代码片段:

测试

//Data doesnt implement the interface

threwExpectedException = false;

    scriptData = ""; //No actual code, shouldn't be a Queue implementation

try{
    Queue queue = scriptToInterfaceFactory.convertScript(scriptLanguage, scriptData, scriptSignature, Queue.class);
    queue.add(""); //Sanity check. Don't want to get here. Throws NoSuchMethodException
} catch(ScriptNotSupportedException e) { threwExpectedException = true; }

assertTrue(threwExpectedException);

转换脚本相关片段

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine scriptEngine = mgr.getEngineByName(engineName);

scriptEngine.eval(scriptData);

Invocable inv = (Invocable) scriptEngine;

/* get interfaceClass object from engine. The interface methods
* should be implemented by script functions with the matching name.
* Will return null if it cannot cast to the interface */
Object interfaceObject = inv.getInterface(interfaceClass);

if(interfaceObject == null) {
    log.trace("Interface Object retreived from script is not the same type as the expected interface");
    throw new ScriptNotSupportedException("Interface Object retreived from script is not the same type as the expected interface");
}

return interfaceClass.cast(interfaceObject);

结果

这条线被击中queue.add(""); //Sanity check. Don't want to get here. Throws NoSuchMethodException,或者如果我删除该健全性检查,基本 AssertTrue 会失败,因为它返回一个 Queue 对象。

问题

如何验证从 ScriptEngine/Invocable 的 getInterface(Class) 方法中提取的对象实际上返回了 Class 接口的完整实现?

4

0 回答 0