Java Language
Verwenden anderer Skriptsprachen in Java
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