Una funzionalità che a molti potrà apparire senza senso, ma che in realtà può venire incontro a diverse situazioni di sviluppo, soprattutto in un ambiente Web based è l'utilizzo di script all'interno del codice Java. In questo articolo impareremo come utilizzare questa funzionalità introdotta a partire da java 1.6.
Sicuramente molti sviluppatori, soprattutto in ambito Web, hanno avuto a che fare con il linguaggio di script, lato client, Javascript. Vedremo che il cosiddetto Java Scripting è un insieme di classi da utilizzare per qualsiasi tipo di scripting, senza riferimento all'ambito Web. Ovviamente, noi per semplicità lo vedremo associato a Javascript, conosciuto ai più, ma la discussione che faremo varrà per tutte le tipologie di linguaggio.
Molti di voi si staranno chiedendo qual è la necessità, dove è il reale utilizzo di un linguaggio di scripting all'interno del codice Java. La risposta ce la dà la Sun dividendo le ragioni in quattro punti:
- Convenienza: generalmente un linguaggio di scripting non ha una forte tipizzazione, quindi possiamo definire una variabile e poi utilizzarla come stringa testuale o come numero;
- Sviluppo di prototipi: più facile sviluppare un prototipo saltando la fase di compilazione;
- Esternalizzare parte delle applicazioni: riutilizzare parti di applicazioni (come metodi o procedure) già scritte nel linguaggio di scripting;
- Avere una shell a mo' di debug: effettuare debug degli script.
Inoltre potreste pensare a creare interessanti interazioni AJAX riferendoci allo sviluppo misto lato client/lato server con la possibilità di passare parametri in maniera intercambiabile tra i due linguaggi. Questa in particolare è una possibilità che potrebbe aprire davvero interessanti fronti di sviluppo, considerando che AJAX è ormai uno standard per sviluppare interfacce web desktop-like.
Ritorniamo alla nuova tecnologia: tutta la logica di scripting è inserita all'interno del package javax.script (JSR 223) e il funzionamento si focalizza sulle seguenti operazioni:
- Esecuzione dello script;
- Binding;
- Compilazione;
- Invocazione;
- Associazione dello script engine da utilizzare.
Per avere informazioni su tutte le classi ed interfacce potete accedere alla descrizione della API
package com.buongiorno.beans;
import java.io.FileNotFoundException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class TestScript {
//Un main utilizzato per richiamare una serie di metodi di test
public static void main(String[] args) throws ScriptException, NoSuchMethodException, FileNotFoundException {
testHello();
testFunction();
testInclude();
}
//Un facile HelloWorld eseguito da script
public static void testHello() throws ScriptException{
//Recupero l'engine script che utilizzerò in seguito
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
//esecuzione del codice javascript
jsEngine.eval("println('Hello, world!')");
}
Il primo metodo, testHello()
è il tipico hello world. Vediamo come nella prima parte definiamo l'engine da utilizzare (Javascript) e nella seconda eseguiamo una semplice stampa a video.
//Definiamo una funzione e la richiamiamo
public static void testFunction() throws ScriptException, NoSuchMethodException{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
/*
* Creiamo la funzione hello() come faremmo in Javascript:
*
* function hello(name){
* print('Hola, ' + name);
* }
*
* ovviamente dobbiamo codificarlo in una stringa
* */
String script = "function hello(name) { println('Hello, ' + name); }";
//Passiamo la funzione all'engine
engine.eval(script);
Invocable inv = (Invocable) engine;
//è come effettuare hello('Pasquale') da script
inv.invokeFunction("hello", "Pasquale" );
}
Nel secondo metodo effettuiamo un'operazione un pò più complessa, cioè, definire una funzione e richiamarla. Come vediamo l'invocazione avviene da linguaggio Java, quindi possiamo pensare ad un interazione con parametri provenienti da un'altra applicazione o da un database.
public static void testInclude() throws FileNotFoundException, ScriptException{
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
//Valuta il contenuto del file passato come riferimento
engine.eval(new java.io.FileReader("include.js"));
}
}
Ultimo metodo che vediamo ci mostra la possibilità di includere un file di script, in cui è contenuta della logica di scripting che il nostro programma andrà ad eseguire. In questo caso, il programma cerca il file include.js che andiamo a definire di seguito:
//include.js
function hello(name,num) {
for(i=0;i<num;i++){
println('Hello, ' + name);
}
}
hello('HTML.IT',5);
Utilizzando il package potrete creare interessanti applicazioni mischiando la potenza di un linguaggio come Java alla flessibilità di un linguaggio di scripting. Inoltre, è possibile utilizzare come script engine qualsiasi presente oppure potrete creare la vostra implementazione. Nell'ultimo caso il linguaggio che creerete dovrà adererire a delle ben precise specifiche (regole di scripting) per poter essere utilizzato dalla JSR citata.