Nahtlose Weitergabe von Arrays und Listen von und nach Nashorn
Ich weiß, dass Sie in Nashorn mit Java-Arrays arbeiten können, und es gibt viele Beispiele dafür. Das Problem bei der Standardmethode ist, dass der Javascript-Code explizit auf seine Laufzeitumgebung aufmerksam gemacht wird. Derzeit habe ich eine Lösung, die Rhino verwendet und nahtlos zwischen Java- und nativen Javascript-Typen konvertiert.
Für Rhino habe ich dies erreicht, indem ich @ implementiert haorg.mozilla.javascript.ContextFactory
undorg.mozilla.javascript.WrapFActory
und EinstellungWrapFactory
auf derContext
wannmakeContext
wird genannt. Diese WrapFactory-Implementierung übernimmt die Konvertierung zwischen Java-Arrays und -Listen sowie nativen JavaScript-Arrays und -Listen. Es ist auch ärgerlich zu erwähnen, dass ich den Rhino-Quellcode vom JDK erhalten musste, um diesen Ansatz zum Laufen zu bringen.
Ich muss eine ähnliche Lösung für Nashorn finden. Hier ist ein Beispiel für das, was ich erreichen möchte.
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();
}
}
Die Ausgabe dieses Codes ist
[I @ 169e6180
[1, 2, 3, 4]
1,2,3,4
Ich suche nach einer Möglichkeit, einen ScriptObjectMirror zu implementieren, vorausgesetzt, dies ist sogar richtig, und dies würde die Ausgabe dieser drei @ bewirkeinvokeFunction
Anrufe sind gleich.
Ich habe versucht mitwrap
Funktion aufScriptUtils
, aber immer noch das Ergebnis ist falsch
AKTUALISIERE
Ich habe versucht, einen dynamischen Proxy vom Typ @ zu erstelleInvocable
und mache Umrechnungen imInvocationHandler
. Um ein NativeArray mit Nashorn zu erstellen, sollten Sie anscheinend @ verwendejdk.nashorn.internal.objects.Global.allocate
, dies löst jedoch immer eine Ausnahme aus.
Global.allocate(new int[] {1, 2, 3, 4})
Raises
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)