Odelia>Technologiesbeta

Introduction au projet cajo avec Groovy

|

cajo est un framework Java puissant, destiné au développement d'applications client/serveur, tout en restant léger et simple à mettre en œuvre.
Nous allons dans cet article, ainsi que dans d'autres à venir, en explorer les principales bases avec des exemples de code en langage Groovy, et même montrer comment ce dernier peut apporter encore plus de concision et de clarté dans l'écriture du code.
Tous ces exemples, composés de scripts Groovy, pourront être exécutés dans la console Groovy, à condition de copier dans le répertoire lib de votre installation Groovy, l'archive cajo.jar du projet cajo.

Pour commencer, en seulement quelques dizaines de ligne de code, nous allons montrer comment exposer un POJO (Plain Old Java Object), ou plutôt un POGO (le G pour Groovy !), placé dans sa JVM, et en invoquer les méthodes depuis une autre JVM.
Nous appellerons serveur la partie de code exposant notre POGO, et client, le code permettant l'invocation distante du POGO. Notez bien que serveur et client ne sont nécessairement sur la même machine physique !


Côté serveur

Si l'on excepte la déclaration de la classe du POGO, seules deux lignes de code suffisent à exposer une instance de celle-ci :

import gnu.cajo.utils.ItemServer
import gnu.cajo.invoke.Remote

class Test {   
    public String echo(String message) {
        println "echo $message"
        message
    }
    public int addition(int a, int b) {
        a + b
    }
}

Remote.config(null, 1198, null, 0)

ItemServer.bind(new Test(), "unNom")

println "Le server s'exécute sur $Remote.serverHost, et le port $Remote.serverPort..."

L'instruction Remote.config définit les paramètres réseaux du serveur, tandis que la seconde, ItemServer.bind enregistre sous le nom logique unNom, le POGO dans le registre RMI local.
A la fin de l'exécution de ce script, notre POGO se retrouve exposé sur la machine locale au travers d'un serveur TCP, sur le port 1198, qui est le port officiellement réservé du projet cajo.


Côté client

Le code client, que vous devez exécuter dans une autre instance de la console Groovy, sur une autre machine par exemple, est tout aussi simple :

import gnu.cajo.invoke.Remote

def serverHost = '...' // Nom de l'hôte (serveur)
def test = Remote.getItem("//${serverHost}:1198/unNom")

assert test.invoke('echo', 'Salut tout le monde !') == 'Salut tout le monde !'
assert test.invoke('addition', [1, 2].toArray()) == 3

Afin d'invoquer notre POGO, nous commençons par en obtenir une référence au moyen de la méthode Remote.getItem et d'une URL composée du nom de la machine hôte, du numéro de port, et du nom logique associé au POJO. Puis, à partir de cette référence, il est possible d'appeler toute méthode public du POGO en utilisant la méthode invoke.
La méthode invoke prend comme arguments le nom de méthode cible à appeler, et une référence pour les arguments à transmettre : cette référence peut valoir null (pas d'argument), être une référence vers un objet (un seul argument), ou bien être un tableau d'objets (plusieurs arguments).

Dans le code Groovy ci-dessus, l'utilisation des assertions permet de vérifier que les appels aux méthodes echo et addition du POGO renvoient bien les résultats attendus.


Un client plus Groovy

Pour la méthode invoke, le projet cajo utilise le mécanisme de réflexion de Java pour invoquer la méthode cible avec les arguments adéquats.
Groovy étant un langage hautement dynamique, nous pouvons arriver à plus de clarté pour l'invocation des méthodes distantes du POGO ; c'est-à-dire pouvoir écrire test.echo('Salut tout le monde !'), au lieu de test.invoke('echo', 'Salut tout le monde !'), et faire comme si echo était vraiment une méthode de test !

Une approche possible consiste à utiliser une classe CajoProxy définie ainsi :

class CajoProxy {
    def item

    CajoProxy(url) {
        item = Remote.getItem(url)
    }

    def methodMissing(String name, args) {
        if (args.length == 1)
            args = args[0]
        item.invoke(name, args)
    }
}

La méthode methodMissing de cette classe sera systématiquement appelée, dès lors que l'on tentera d'invoquer une méthode inconnue sur une instance de la classe CajoProxy.
methodMissing recevant le nom de la méthode manquante ainsi que les arguments utilisés, l'implémentation fait alors un appel à invoke.

Voici donc le code client, rendu plus Groovy, grâce à la classe CajoProxy :

import gnu.cajo.invoke.Remote

class CajoProxy {
    def item

    CajoProxy(url) {
        item = Remote.getItem(url)
    }

    def methodMissing(String name, args) {
        if (args.length == 1)
            args = args[0]
        item.invoke(name, args)
    }
}

def serverHost = '...' // // Nom de l'hôte (serveur)
def test = new CajoProxy("//${serverHost}:1198/unNom")

assert test.echo('Salut tout le monde !') == 'Salut tout le monde !'
assert test.addition(1, 2) == 3

Nous arrivons ainsi à plus de concision et de clarté !

Par ailleurs, nous voyons que la valeur d'affectation de la référence test pourrait très bien être un objet local (à condition que la définition de la Test soit accessible côté client) et non distant, et le reste du code rester complètement identique !

balises dans Langages et systèmes

AJAX cajo Camel DSL Grails Groovy Java JBI prefuse RSS ServiceMix SOA