Попробуйте это и посмотрите. Это печатает «неопределенное», а затем завершается с TypeError: [[email protected]] не имеет такой функции «GetBar»Невозможно прочитать свойства объекта, переданного из Java в качестве аргумента функции?
Теперь проблема здесь не в том, что Nashorn должна быть в состоянии получить доступ к свойствам бин данных с их имена, без необходимости вызывать функцию - например, ab вместо a.getB(). Этот пример, однако, показывает, что этот вид доступа читает «undefined» вместо значения String «localBar»; и основная функция getBar() не видна вообще! Благодаря переопределенному toString() сообщение об исключении доказывает, что вызов foo.getBar() из Java отлично работает.
Что происходит?
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class NashornJS {
public static void main(String[] args) throws Exception {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("nashorn");
final String localBar = "localBar";
final Object foo = new Object() {
public final String getBar() { return localBar; }
@Override public String toString() { return "[inner="+getBar().toString()+"]"; }
};
try {
scriptEngine.eval("function test(foo) { print(foo.bar); print(foo.getBar()); }");
((Invocable)scriptEngine).invokeFunction("test", foo);
} catch (final ScriptException se) {
se.printStackTrace();
}
}
}
Интересно, что если я объявляю «нормальный» класс Foo, Нашорн читает его правильно. Если я не сделаю Foo * private *. Поэтому я могу предположить, что эта проблема имеет какое-то отношение к анонимным классам, являющимся непубличными (хотя я не могу точно догадаться, почему это должно быть публично, и, кроме того, JS на самом деле * мог видеть это свойство, просто не мог прочитать его значение!) –