So che puoi lavorare con gli array Java in Nashorn e ci sono molti esempi su come farlo. Il problema per me con l'approccio standard è che rende il codice javascript esplicitamente a conoscenza del suo ambiente di runtime. Attualmente ho una soluzione che fa uso di Rhino e converte senza soluzione di continuità tra tipi Java e tipi javascript nativi.Passa senza problemi a array e elenchi da e verso Nashorn
Per rinoceronte ho compiuto questo implementando org.mozilla.javascript.ContextFactory
e org.mozilla.javascript.WrapFActory
e impostazione WrapFactory
sul Context
quando makeContext
è chiamato. Questa implementazione di WrapFactory si occupa della conversione tra array Java ed elenchi e matrici ed elenchi javascript nativi. Inoltre, ha detto che dovevo ottenere il codice sorgente di Rhino dal JDK per far funzionare questo approccio.
Ho bisogno di trovare una soluzione simile per Nashorn. Ecco un esempio di ciò che sto cercando di realizzare.
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();
}
}
L'uscita di questo codice è
[I @ 169e6180
[1, 2, 3, 4]
1,2,3,4
Sto cercando un modo per implementare uno ScriptObjectMirror, supponendo che sia anche corretto, che renderebbe l'output di queste tre chiamate invokeFunction
sono uguali.
Ho provato con wrap
funzione ScriptUtils
, ma ancora il risultato è sbagliato
UPDATE
Ho cercato di creare un proxy dinamica di tipo Invocable
e fare conversioni in InvocationHandler
. Per creare un NativeArray con Nashorn sembra che dovresti usare jdk.nashorn.internal.objects.Global.allocate
, ma questo solleva sempre un'eccezione.
Global.allocate(new int[] {1, 2, 3, 4})
Aumenta
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)
vostro 'Arrays.asList()' chiamata sembra creare una lista con un unico elemento di tipo 'int []' invece di quello che vuoi. Prova invece 'Arrays.asList (1,2,3,4)'. – biziclop
ah, grazie :) Questo rende le cose un po 'migliori. Aggiornerò la domanda – Leon
Non è il problema principale qui che gli array JS non sono in realtà matrici in senso Java?Sono più come mappe con una chiave 'int'. – biziclop