Ich verwende Nashorn über JSR 223, um kleine Snippets des vom Benutzer eingegebenen Skripts auszuführen:
%Vor%Das variierende Benutzerskript ruft JavaScript-Funktionen auf, die in einer statischen, zentralen Bibliothek definiert sind (in% code_% im obigen Codefragment enthalten).
Jedes Mal, wenn ich ein functions
erhalten möchte, das ich von meinem Java aus aufrufen kann, muss ich den großen Bibliothekscode ständig neu kompilieren.
Gibt es eine Möglichkeit, einem zuvor kompilierten Code mit neuem Code beizutreten?
Dies ist ein Design von JSR-223; eval(String)
kann nicht wirklich einen Code-Cache hinter sich haben. Nun, theoretisch könnte es, aber es würde eine Menge Spekulationen auf Seiten dessen enthalten, was der Entwickler will (und wie alle Spekulationen, es würde zwangsläufig falsch sein).
Was Sie tun sollten, ist, Ihr Invocable
einmal auszuwerten, es herumzuhalten und es wiederholt zu verwenden.
Beachten Sie dabei, dass Nashorn keine Threadsicherheit bietet (JavaScript hat kein Threading-Konzept, daher ist Nashorn absichtlich nicht threadsicher, um Synchronisationskosten nicht bezahlen zu müssen, wenn sie nicht von der Sprachsemantik vorgegeben werden) . Aus diesem Grund ist Ihre erstellte Invocable
nicht sicher für die Verwendung mehrerer Threads im Hinblick auf den Status der globalen Variablen im zugrunde liegenden Skript. (Gleichzeitig ausgeführte Funktionen, die nicht mit dem globalen Status des Skripts interagieren, sind in Ordnung.)
Wenn Sie es über Threads teilen müssen und hängen die Funktionen vom globalen Status ab, und kann sich der globale Status ändern, dann müssen Sie Ihr eigenes Scaffolding hinzufügen Dafür (entweder Synchronisierung oder Ressourcen-Pooling oder was auch immer sonst gerade in Mode ist).
Wenn Sie vorkompilieren und JavaSctipt-Funktionen mit verschiedenen Argumenten aufrufen müssen, können Sie sie separat kompilieren und den Ausführungsfluss in Java zusammenstellen. Mit JavaScript-Engine Nashorn in Java8 können Sie tun:
%Vor%Sie können Java-Objekte innerhalb von JavaSctipt übergeben, siehe Beispiel oben mit java.util.HashMap.
Ausgabe ist:
%Vor%