Suche…


Einführung

Java an sich ist eine extrem mächtige Sprache, die jedoch dank JSR223 (Java Specification Request 223), einer Skript-Engine, noch erweitert werden kann

Bemerkungen

Die Java Scripting API ermöglicht die Interaktion externer Skripts mit Java

Die Skript-API kann die Interaktion zwischen dem Skript und Java ermöglichen. Die Skriptsprachen müssen über eine Implementierung von Script Engine im Klassenpfad verfügen.

Standardmäßig wird JavaScript (auch als ECMAScript bezeichnet) standardmäßig von nashorn bereitgestellt. Jede Script Engine verfügt über einen Skriptkontext, in dem alle Variablen, Funktionen und Methoden in Bindungen gespeichert werden. Manchmal möchten Sie möglicherweise mehrere Kontexte verwenden, da diese die Umleitung der Ausgabe auf einen gepufferten Writer und einen anderen Fehler unterstützen.

Es gibt viele andere Skript-Engine-Bibliotheken wie Jython und JRuby. Solange sie sich auf dem Klassenpfad befinden, können Sie Code überprüfen.

Wir können Bindungen verwenden, um Variablen im Skript anzuzeigen. Wir benötigen in einigen Fällen mehrere Bindungen, da das Aussetzen von Variablen an die Engine im Wesentlichen nur das Aussetzen von Variablen für diese Engine ermöglicht. In manchen Fällen müssen bestimmte Variablen wie Systemumgebung und Pfad für alle Engines desselben Typs verfügbar gemacht werden. In diesem Fall benötigen wir eine globale Bindung. Durch das Aussetzen von Variablen werden alle Skriptmodule von derselben EngineFactory erstellt

Evaluierung Eine Javascript-Datei im -scripting-Modus von nashorn

public class JSEngine {
    
    /*
    * Note Nashorn is only available for Java-8 onwards
    * You can use rhino from ScriptEngineManager.getEngineByName("js");
    */
    
    ScriptEngine engine;
    ScriptContext context;
    public Bindings scope;
    
    // Initialize the Engine from its factory in scripting mode
    public JSEngine(){
        engine = new NashornScriptEngineFactory().getScriptEngine("-scripting");
        // Script context is an interface so we need an implementation of it
        context = new SimpleScriptContext();
        // Create bindings to expose variables into
        scope = engine.createBindings();
    }
    
    // Clear the bindings to remove the previous variables
    public void newBatch(){
        scope.clear();
    }
    
    public void execute(String file){
        try {
            // Get a buffered reader for input
            BufferedReader br = new BufferedReader(new FileReader(file));
            // Evaluate code, with input as bufferdReader
            engine.eval(br);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ScriptException ex) {
            // Script Exception is basically when there is an error in script
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void eval(String code){
        try {
            // Engine.eval basically treats any string as a line of code and evaluates it, executes it
            engine.eval(code);
        } catch (ScriptException ex) {
            // Script Exception is basically when there is an error in script
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    // Apply the bindings to the context and set the engine's default context
    public void startBatch(int SCP){
        context.setBindings(scope, SCP);
        engine.setContext(context);
    }
    
    // We use the invocable interface to access methods from the script
    // Invocable is an optional interface, please check if your engine implements it
    public Invocable invocable(){
        return (Invocable)engine;
    }
    
}

Nun die Hauptmethode

public static void main(String[] args) {
    JSEngine jse = new JSEngine();
    // Create a new batch probably unecessary
    jse.newBatch();
    // Expose variable x into script with value of hello world
    jse.scope.put("x", "hello world");
    // Apply the bindings and start the batch
    jse.startBatch(ScriptContext.ENGINE_SCOPE);
    // Evaluate the code
    jse.eval("print(x);");
}

Ihre Ausgabe sollte ähnlich sein
hello world

Wie Sie sehen, wurde die exponierte Variable x gedruckt. Testen Sie jetzt mit einer Datei.

Hier haben wir test.js

print(x);
function test(){
    print("hello test.js:test");
}
test();

Und die aktualisierte Hauptmethode

public static void main(String[] args) {
    JSEngine jse = new JSEngine();
    // Create a new batch probably unecessary
    jse.newBatch();
    // Expose variable x into script with value of hello world
    jse.scope.put("x", "hello world");
    // Apply the bindings and start the batch
    jse.startBatch(ScriptContext.ENGINE_SCOPE);
    // Evaluate the code
    jse.execute("./test.js");
}

Angenommen, test.js befindet sich in demselben Verzeichnis wie Ihre Anwendung. Sie sollten eine ähnliche Ausgabe haben

hello world
hello test.js:test


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow