Java Scripting

Posted in Java/J2EE on mai 28th, 2009 by Ajrarn

… depuis sa version 6, Java intègre une nouvelle fonctionnalité nommée : Java Scripting.
Comme son nom l’indique plus ou moins, cela permet de manipuler directement des langages de script dans vos classes Java.

Vous vous demandez peut-être l’intérêt qu’il y a à procéder de la sorte, mais si si, il y en a!
Pour rappel, pour beaucoup de langages de script :

  • Il n’y a pas de typages, ou pas de typages obligatoires.
  • Pas de compilation à gérer, un déploiement trivial, bien adapté au développement de prototypes par exemple.
  • Il y a certaines fonctionnalités très appréciables comme la lecture d’un fichier XML de manière très simple.

Cette nouvelle fonctionnalité permet de manipuler un grand nombre de langages de script, dont les suivants : Groovy, Jaskell, Python, Ruby, Velocity, XPath, XSLT pour ne nommer qu’eux (ou plutôt que ceux que je connais! (^_^) ). L’utilisation de l’un d’entre eux vous demandera d’ajouter le jar adéquat dans votre projet.

Par contre, nativement, Java 6 intègre Rhino : Javascript for java, un projet Mozilla.

Alors, comment ça marche?
Commençons par un exemple simple. Imaginons que nous ayons un fichier add10.js contenant le code suivant :

var j = 10;
println(i + j);

Voici un exemple, en Java, montrant comment injecter une variable dans ce code javascript et le jouer :

import java.io.FileNotFoundException;
 
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class TestScripting {
	public static void main(String[] args) {
	// Création du manager du moteur de script
        ScriptEngineManager factory = new ScriptEngineManager();
        // Création du moteur Javascript
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        try {
        	int a = 10;
        	// On fournit la variable "i" au code Javascript
        	engine.put("i", a);
        	// Evaluation du code du fichier add10.js
		engine.eval(new java.io.FileReader("script/add10.js"));
		} catch (ScriptException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}

En exécutant ce fichier Java, vous devriez voir la valeur 20 apparaître dans votre console de sortie.

Allons un peu plus loin.
Considérons que nous avons une classe Java nommée Person et définie comme suit :

public class Person {
	public String firstName;
	public String lastName;
	public int age;
 
	Person (String firstName, String lastName, int age) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}
}

Et le fichier Javascript infoPerson.js suivant :

function getAge(person) {
	return person.age;
}
 
function getFirstName(person) {
	return person.firstName;
}
 
function getLastName(person) {
	return person.lastName;
}

Voici comment appeler une méthode Javascript, en lui passant un paramètre (objet qui plus est) et en récupérer le résultat :

import java.io.FileNotFoundException;
 
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
 
public class TestScripting {
	public static void main(String[] args) {
		// Création du manager du moteur de script
		ScriptEngineManager factory = new ScriptEngineManager();
		// Création du moteur Javascript
		ScriptEngine engine = factory.getEngineByName("JavaScript");
		try {
			Person person = new Person("Pascal", "VERRECCHIA", 29);
 
			// Evaluation du code du fichier infoPerson.js
			engine.eval(new java.io.FileReader("scripts/infoPerson.js"));
 
			Invocable inv = (Invocable) engine;
			// Appel de la méthode Javascript "getAge" en passant l'objet person
			// en paramètre et cast du résultat pour obtenir un entier.
			int age = (Integer) inv.invokeFunction("getAge", person);
 
			System.out.println("age : " + age);
		} catch (ScriptException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
}

Vous devriez voir age : 29 dans votre console après exécution de ce code Java.
Vous aurez remarqué que le fait d’envoyer un objet au Javascript ne pose pas de problèmes!
La valeur retournée par une méthode Javascript est de type Object. Il sera donc nécessaire de parser le résultat en conséquence.

Voilà pour les grandes lignes du Java Scripting.
Si vous souhaitez aller plus loin, allez vous promener par .

Un petit bémol, cependant, concernant l’intégration de Rhino dans Java 6 : toute la partie E4X (ECMAScript for XML) a été exclue… Et ça, c’est bien dommage, parce que E4X, pour travailler sur du XML, c’est tout de même sacrément sympa…

Si c’est ce type de besoin que vous recherchez, je vous conseille de vous orienter vers Groovy et/ou XPath.

Tags: ,