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. Vediamo con qualche esempio il funzionamento concreto effettuando alcune tipiche operazioni di script, utilizzando l'engine Javascript:
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.