У меня есть скрипт JavaScript, который выглядит примерно так:
function run(database) {
var result = database.query("query", "some resource name");
//operations on result
return result;
}
и у меня есть код Java, который выполняет скрипт, который выглядит примерно так:
public Object execute(String script, Database database) {
NashornScriptEngineFactory nsef = new NashornScriptEngineFactory();
ScriptEngine engine = nsef.getScriptEngine();
try {
engine.eval(script);
Invocable invocable = (Invocable) engine;
return invocable.invokeFunction("run", database);
} catch(ScriptException e) {
throw new RuntimeException(e);
}
}
Database
— это интерфейс, который содержит определения нескольких методов, но не содержит метод query
. Я вызываю execute
с реализацией Database
, назову ее DatabaseImpl
, которая действительно имеет метод query
. Это будет полиморфно, и ожидается, что скрипт знает, какие методы доступны для экземпляра Database
, переданного ему. Я решил не использовать дженерики с этим, поскольку они стираются во время выполнения, и поэтому JavaScript все равно не может их использовать, поэтому автор сценария должен правильно определить типы.
Однако, когда я запускаю этот код, я получаю следующее исключение:
javax.script.ScriptException: TypeError: database.query is not a function in <eval> at line number 25
По сути, суть в том, что у меня есть объект, который реализует интерфейс, и вызываю метод, который реализует конкретный экземпляр, но не является частью определения интерфейса. У меня сложилось впечатление, что это все еще должно работать, но это не так. Для меня не имеет особого смысла, что мне нужно будет выполнить подкаст внутри скрипта, чтобы иметь доступ к методу query
(возможно ли это вообще?), так почему я получаю эту ошибку? Это потому, что метод недоступен из определения интерфейса? Есть ли обходной путь?
Спасибо.