Java Language
Utiliser d'autres langages de script en Java
Recherche…
Introduction
Java en soi est un langage extrêmement puissant, mais sa puissance peut encore être étendue Grâce à JSR223 (Java Specification Request 223), qui introduit un moteur de script
Remarques
L'API de script Java permet aux scripts externes d'interagir avec Java
L'API de script peut permettre une interaction entre le script et Java. Les langages de script doivent avoir une implémentation de Script Engine sur le classpath.
Par défaut, JavaScript (également appelé ECMAScript) est fourni par nashorn par défaut. Chaque moteur de script a un contexte de script où toutes les variables, fonctions et méthodes sont stockées dans des liaisons. Parfois, vous pouvez utiliser plusieurs contextes car ils prennent en charge la redirection de la sortie vers un enregistreur en mémoire tampon et une erreur vers une autre.
Il existe de nombreuses autres bibliothèques de moteur de script comme Jython et JRuby. Tant qu'ils sont sur le classpath, vous pouvez évaluer le code.
Nous pouvons utiliser des liaisons pour exposer des variables dans le script. Dans certains cas, nous avons besoin de plusieurs liaisons, car l'exposition des variables au moteur consiste essentiellement à exposer les variables uniquement à ce moteur. Parfois, nous devons exposer certaines variables comme l'environnement système et le chemin d'accès pour tous les moteurs du même type. Dans ce cas, nous avons besoin d'une liaison de portée globale. Exposition de variables à ceux qui l'exposent à tous les moteurs de script créés par le même EngineFactory
Évaluation d'un fichier javascript en mode script de 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;
}
}
Maintenant la méthode principale
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);");
}
Votre sortie devrait être similaire à celle-ci
hello world
Comme vous pouvez le voir, la variable exposée x a été imprimée. Maintenant, testez avec un fichier.
Ici nous avons test.js
print(x);
function test(){
print("hello test.js:test");
}
test();
Et la méthode principale mise à jour
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");
}
En supposant que test.js se trouve dans le même répertoire que votre application Vous devriez avoir une sortie similaire à celle-ci
hello world
hello test.js:test