Java Language
Andere scripttalen gebruiken in Java
Zoeken…
Invoering
Java is op zichzelf een extreem krachtige taal, maar de kracht ervan kan verder worden uitgebreid dankzij JSR223 (Java Specification Request 223) die een script-engine introduceert
Opmerkingen
Met de Java Scripting API kunnen externe scripts communiceren met Java
De Scripting API kan interactie tussen het script en Java mogelijk maken. De scripttalen moeten een Script Engine-implementatie op het klassenpad hebben.
Standaard wordt JavaScript (ook bekend als ECMAScript) standaard geleverd door nashorn. Elke Script Engine heeft een scriptcontext waarin alle variabelen, functies en methoden worden opgeslagen in bindingen. Soms wilt u misschien meerdere contexten gebruiken omdat deze de uitvoer omleiden naar een gebufferde writer en een fout naar een andere.
Er zijn veel andere script-engine-bibliotheken zoals Jython en JRuby. Zolang ze zich op het klassenpad bevinden, kunt u code evalueren.
We kunnen bindingen gebruiken om variabelen in het script bloot te leggen. We hebben in sommige gevallen meerdere bindingen nodig, omdat het blootstellen van variabelen aan de motor in feite variabelen alleen aan die motor blootstelt, soms moeten we bepaalde variabelen blootleggen, zoals systeemomgeving en pad die hetzelfde is voor alle motoren van hetzelfde type. In dat geval hebben we een binding nodig die een wereldwijde reikwijdte heeft. Door variabelen hieraan bloot te stellen, wordt deze blootgesteld aan alle script-engines die door dezelfde EngineFactory zijn gemaakt
Evaluatie van een javascript-bestand in -scripting-modus van 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;
}
}
Nu de belangrijkste methode
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);");
}
Je output zou er ongeveer hetzelfde uit moeten zien
hello world
Zoals u kunt zien, is de belichte variabele x afgedrukt. Nu testen met een bestand.
Hier hebben we test.js
print(x);
function test(){
print("hello test.js:test");
}
test();
En de bijgewerkte hoofdmethode
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");
}
Ervan uitgaande dat test.js zich in dezelfde map bevindt als uw toepassing, zou u een vergelijkbare uitvoer moeten hebben
hello world
hello test.js:test