Плавно передавайте массивы и списки в и из Нашорна
Я знаю, что вы можете работать с массивами Java в Nashorn, и есть множество примеров, как это сделать. Проблема для меня со стандартным подходом состоит в том, что он делает код javascript явно осведомленным о своей среде выполнения. В настоящее время у меня есть решение, которое использует Rhino, и оно плавно конвертирует между типами Java и Native Javascript.
Для Rhino я достиг этого, реализовавorg.mozilla.javascript.ContextFactory
а такжеorg.mozilla.javascript.WrapFActory
и настройкаWrapFactory
наContext
когдаmakeContext
называется. Эта реализация WrapFactory заботится о преобразовании между массивами Java и списками, а также массивами и списками собственного javascript. Также стоит упомянуть, что мне пришлось получить исходный код Rhino от JDK, чтобы этот подход заработал.
Мне нужно найти подобное решение для Nashorn. Вот пример того, чего я пытаюсь достичь.
public static void main(String args[]) {
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine();
try {
engine.eval("function print_array(arr) { print(arr); }");
engine.eval("function print_native() { print_array([1, 2, 3, 4]); }");
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("print_array", new int[]{1, 2, 3, 4});
invocable.invokeFunction("print_array", Arrays.asList(1, 2, 3, 4));
invocable.invokeFunction("print_native");
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
Выход этого кода
[I @ 169e6180
[1, 2, 3, 4]
1,2,3,4
Я ищу способ реализовать ScriptObjectMirror, предполагая, что это даже правильно, что бы сделать вывод этих трехinvokeFunction
звонки будут одинаковыми.
Я пытался использоватьwrap
функция наScriptUtils
, но все равно результат неправильный
ОБНОВИТЬ
Я пытался создать динамический прокси типаInvocable
и делать преобразования вInvocationHandler
, Похоже, что для создания NativeArray с помощью Nashorn вам следует использоватьjdk.nashorn.internal.objects.Global.allocate
, но это всегда вызывает исключение.
Global.allocate(new int[] {1, 2, 3, 4})
Повышения
Exception in thread "main" java.lang.NullPointerException
at jdk.nashorn.internal.objects.Global.instance(Global.java:491)
at jdk.nashorn.internal.objects.NativeArray.<init>(NativeArray.java:141)
at jdk.nashorn.internal.objects.Global.allocate(Global.java:1584)