Ich weiß, dass Sie mit Java-Arrays in Nashorn arbeiten können und es gibt viele Beispiele dafür, wie Sie dies tun. Das Problem für mich mit dem Standardansatz ist, dass es den JavaScript-Code explizit auf seine Laufzeitumgebung aufmerksam macht. Derzeit habe ich eine Lösung, die Rhino verwendet und es nahtlos zwischen Java-Typ und Native-Javascript-Typen konvertiert.Nahtlos Pass Arrays und Listen zu und von Nashorn
Für Rhino erreichte ich dies durch org.mozilla.javascript.ContextFactory
und org.mozilla.javascript.WrapFActory
Implementierung und WrapFactory
auf dem Context
Einstellung, wenn makeContext
genannt wird. Diese WrapFactory-Implementierung kümmert sich um die Konvertierung zwischen Java-Arrays und Listen und nativen Javascript-Arrays und -Listen. Es wurde auch erwähnt, dass ich den Rhino-Quellcode vom JDK bekommen musste, damit dieser Ansatz funktioniert.
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();
}
}
Der Ausgang dieses Codes ist
[I @ 169e6180
[1, 2, 3, 4]
1,2,3,4
Ich bin auf der Suche nach einer Möglichkeit, einen ScriptObjectMirror zu implementieren, vorausgesetzt, dass sogar richtig ist, dass die Ausgabe machen würde von diesen drei invokeFunction
Anrufe gleich sein.
Ich habe versucht, mit wrap
Funktion auf ScriptUtils
, aber immer noch das Ergebnis ist falsch
UPDATE
Ich habe versucht, einen dynamischen Proxy-Typ zu schaffen Invocable
und Konvertierungen in der InvocationHandler
. Um ein NativeArray mit Nashorn zu erstellen, sollten Sie jdk.nashorn.internal.objects.Global.allocate
verwenden, was jedoch immer eine Ausnahme auslöst.
Global.allocate(new int[] {1, 2, 3, 4})
Lösen
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)
Ihre 'Arrays.asList()' Anruf erscheint eine Liste mit einem Element des Typs zu schaffen, 'int []' anstatt was du willst. Probieren Sie stattdessen "Arrays.asList (1,2,3,4)". – biziclop
ah, danke :) Das macht die Dinge ein wenig besser. Ich werde die Frage aktualisieren – Leon
Ist nicht das Hauptproblem hier, dass JS-Arrays nicht eigentlich Arrays im Java-Sinne sind?Sie sind mehr wie Karten mit einer "int" -Taste. – biziclop