我很高兴将ScriptEngine合并到我的代码库中,并计划使用它来从持久化脚本中动态构建接口实现。
我正在编写我的JUnit测试用例,用于将脚本数据转换为Java接口实例的一般实现。我似乎发现你不需要在脚本中实际实现整个接口,以便Invocable.getInterface(Class<?>)
将其视为该接口的对象。根据{{1}}的文档,我认为如果没有给出完整的实现,我可以指望它返回null:
getInterface
使用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)
似乎总是返回true。我猜测将动态类型脚本语言实现映射到静态类型Java接口存在概念上的挑战。但是,如果您尝试在此对象上调用任何未实现的方法,则会出现Invocable.getInterface(Class<?>)
。
以下是一些有助于说明的代码片段:
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);
或者如果我删除该Sanity检查,则基本的AssertTrue失败,因为它返回一个Queue对象。
如何验证从ScriptEngine / Invocable的getInterface(Class)方法中提取的对象是否实际返回了Class接口的完整实现?