Fedora-Fr - Communauté francophone Fedora - Linux

Planet de Fedora-Fr : la communauté francophone autour de la distribution Linux Fedora

A propos

Cette page est actualisée toutes les heures.

Cette page est une sélection de blogs autour de Fedora. Fedora-Fr.org décline toute responsabilité au sujet des propos tenus par les auteurs des blogs de ce planet. Leurs propos sont leur entière responsabilité.

Le contenu de ce planet appartient à leurs auteurs respectifs. Merci de consulter leur blogs pour obtenir les licences respectives.

Install Party: Sup'Info...on y était...

Fedora Lyon

Bonjour à tous!

Ce samedi 27 novembre 2010, de 10 h à 17 h, une install party était organisée par le Labo-Linux Lyon de SUPINFO, en collaboration avec l'ALDIL et des communautés Linux. Fedora était bien de la party ;)" class="smiley

De belles salles, bien équipées avec de la fibre optique...

Il y a eu pas mal de monde, surtout l'après-midi.

Pas de demande d'install Fedora mais Haikel, Yann et moi avons aidé dans les différents problèmes techniques, configurations et autres. Agrémentés de discussions interessentes.

Une bonne journée en somme.

Pour rappel Le lieu : "SUPINFO Lyon" : Les Jardins d'Osaka 16 rue Jean Desparmet. 69008 LYON

Passez tous un bon we!

kiko

Cluster haute disponibilité

Antoine Wallon Famillewallon.com s’enrichit avec un service de haute disponibilité apache basé sur heartbeat il fonctionne maintenant avec tout mes sites. voici un petit aperçu de cette nouvelle fonctionnalité Seul apache est en Haute disponibilité pour le moment. Par la suite le service MySQL et une haute disponibilité sur les fichiers seront mis en place.

création d’une machine xen et mise en place d’un serveur web (Abiss)

Antoine Wallon Famillewallon.com dispose maintenant d’un serveur Web dédié (sous paravirtualisation Xen). ce serveur virtuel est mis en place sur le serveur Physique ACTES. il gère actuellement tout mes sites (*.famillewallon.com et le site de mon nouveau projet alphanetwork)

FOSDEM 2011

Pierre-Yves Chibon

English version

fosdem.png

Fosdem 2011 is still pretty far away (5-6 of February) but I can already say that I will be there !

PHP 5.3.4 en préparation

Remi Collet

PHP 5.3.4RC1 est annoncée. Les RPM sont disponibles dans le dépôt remi-test pour fedora 12, 13, 14, EL 5 et 6.

Les RPM sont reconstruits régulièrement à partir des derniers clichets SVN. Version actuelle : 5.3.4-0.1.201011270530 (5.3.4RC2-dev) Pour installer et tester cette nouvelle version, qui devrait corriger pas mal de bugs : yum --enablerepo=remi-test update phpJ'attends vos retours,  sur le forum. Cette version est déjà installée sur mon dédié.... Lire PHP 5.3.4 en préparation

Renommer un groupe de volumes

Marc Bessière Vous est-il déjà arrivé de devoir connecter à votre machine un disque externe sur lequel un groupe de volumes porte le même nom que celui que vous utilisez ? Pas de panique, il y a une solution. La commande vgscan nous liste les groupes de volumes disponibles : Reading all physical volumes. This may take [...]

mysql-worbench-5.2.30

Remi Collet

MySQL Worbench, l'outil de modélisation graphique, de développement, de requêtage et d'administration des bases de données MySQL passe en version 5.2.30 (GA = stable). Les RPM pour Fedora ≥ 11 sont disponibles dans le dépôt remi et dans le dépôt updates-testing pour fedora ≥ 13.

Voir la Releases Page pour la liste des modifications ou Changes in MySQL Workbench 5.2.30. Les RPM sont désormais dans les dépôts officiels de fedora ≥ 13, il sont aussi dans mon dépôt pour Fedora ≥ 11. Les plus anciennes versions ne disposent pas des dépendances nécessaires, notament boost ≥ 1.37.0. Comme toujours : yum --enablerepo=remi... Lire mysql-worbench-5.2.30

Fin de vie pour la Fedora 12

Edouard Bourguignon

Juste un petit rappel pour ceux qui n'auraient pas vu passer l'information, la Fedora 12 arrive au terme de son cycle de maintenance le 2 décembre prochain. Il n'y aura donc plus de mises à jour à partir de cette date, pensez donc à passer à une version plus récente (tant qu'à faire autant partir sur l'excellente Fedora 14).

Source

Mardi Artistique : Plymouth - Thème Spinfinity

Paquet Fedora du jour

Il existe plusieurs thème Plymouth, voici plymouth-theme-spinfinity !

Ce paquet contient le thème de démarrage graphique pour plymouth nommé "Spinfinity". Cela affiche Fedora avec une trace dessinant le signe infinité.

Pour pouvoir utiliser ce type, vous devez au préalable avoir suivi les instructions d'installation de Plymouth

plymouth-theme-spinfinity Installation en ligne de commande : yum install plymouth-theme-spinfinity

Installation avec l'interface graphique : Autres > Plymouth "Spinfinity" Theme

Lancement en ligne de commande : plymouth-set-default-theme spinfinity /usr/libexec/plymouth/plymouth-update-initrd








Scripts JS avec Java et Rhino : mise en œuvre avec un bot IRC

Fabien Nicoleau

Je montrais dans mon billet précédent que grâce à Rhino il est possible d'exécuter du code JavaScript depuis un programme Java, et comment il possible de se servir de ce système pour gérer des plugins. Je propose dans ce billet de mettre en œuvre ces fonctionnalités et de les appliquer à un projet simple : un robot IRC modulaire. Le principe est d'avoir un robot écrit en Java et capable de se connecter à un serveur IRC, puis de communiquer avec lui (envoi et réception de messages). Nous n'ajouterons rien à ce programme Java, aucun savoir faire pour ce robot, à une exception prêt : la possibilité de stocker des plugins qui lui permettront d'avoir de nouvelles fonctionnalités. Attention, le sujet de ce billet n'étant pas le codage d'un robot IRC (il y en a de meilleurs pour ca ^^), celui présenté ici est ultra simple, et se contente du minimum.

Pour comprendre ce programme, il faut avoir quelques notions sur Rhino/Java, des notions sur les expressions régulières, et notamment les groups qui seront bien utiles ici, et savoir en gros ce qu'est un client IRC.

Le décor

Le programme sera donc codé en Java. Une classe JIrcRobot se chargera de se connecter au serveur IRC, et de communiquer avec lui. Une interface permettra de définir les méthodes à implémenter par les plugins. Elle sera originalement nommée Plugin. La classe JIrcRobot chargera les plugins disponibles, c'est à dire ceux contenus dans le dossier originalement nommé plugins et dont l'extension est .js, puisqu'ils contiennent du code JavaScript. Cela permettra aussi de pouvoir désactiver le chargement d'un plugin en modifiant simplement son extension. Une fois les plugins chargés, le programme attendra des messages du serveur. A chaque message reçu, il interrogera tout ses plugins pour savoir si l'un d'eux est concerné par le message. Si c'est le cas, le plugin sera alors exécuté et pourra alors réagir en envoyant des messages au serveur IRC.

Le test

Pour ceux qui préfèrent voir les choses fonctionner tout de suite, et voir comment ca marche, je vous propose de tester tout de suite le programme. Il vous faut récupérer tous les fichiers en annexe de ce programme : le fichier JIrcRobot.java ainsi que tous les fichiers en .js, qui seront à mettre dans un dossier nommé plugins. JIrcRobot.java sera à mettre au même niveau d'arborescence que le dossier plugins. Vous pouvez sinon juste prendre le fichier jircrobot.tar.gz et le décompresser.

Ouvrez ensuite le fichier JIrcRobot.java et éditez les paramètres de connexion, situés sous le commentaire "CONFIGURATION DE LA CONNEXION AU SERVEUR" pour donner un pseudonyme au robot, lui indiquer sur quel serveur il doit se connecter, et quels canaux il doit rejoindre. Sauvegardez les modifications et compilez le programme :

javac JIrcRobot.java

Vous pouvez maintenant l'exécuter :

java JIrcRobot

Le robot charge les plugins puis se connecte au serveur. En l'état actuel, le robot est capable de répondre aux PING du serveur, afin qu'il ne coupe pas la connexion, de rejoindre des canaux de discussion, de se présenter quand il rejoint un canal et souhaiter la bienvenue à ceux qui arrivent ensuite, de se couper si quelqu'un tape "!QUIT" et enfin de crier "COCORICO" si une phrase contient "france". Ces fonctionnalités sont toutes apportées par les plugins. Le programme Java en lui même ne sait rien faire de tout ca.

La classe JIrcRobot

Il est maintenant temps de comprendre comment tout cela fonctionne. Je passe rapidement sur les fonctionnalités liées au protocole IRC. Sans entrer dans le code, il faut juste savoir que la classe propose ces méthodes :

connect() : se connecte au serveur IRC
getNickName() : renvoie le pseudonyme du robot
joinChannels() : envoie les commandes au serveur IRC pour rejoindre des canaux de discussion
loadPlugins() : charge tous les plugins disponibles dans un dossier
readLine() : lis un message provenant du serveur, s'il y en a un d'arrivé
run() : boucle conservant la connexion avec le serveur, et exécutant les plugins si besoin
setStayConnected() : permet d'indiquer si l'on souhaite rester connecté au serveur ou non
write() : envoi un message au serveur IRC


Les méthodes importantes seront détaillées ensuite : loadPlugins et run.

Enfin la classe contient une interface privée, Plugin, qui permet de définir les méthodes que devront implémenter les plugins :

getPattern() : retournera l'expression régulière qui si elle est validée, indiquera que le plugin doit réagir au message arrivé
patternMatch() : cette méthode sera appelée si l'expression régulière du plugin match avec le message arrivé

Nos plugins devront donc implémenter ces deux méthodes.

Le programme Java

Après avoir vu les méthodes permettant de dialoguer avec le serveur, intéressons nous, dans le détail cette fois-ci, au code des deux principales. Avant cela, un rapide coup d'œil à la méthode main du programme :

public static void main(String[] args) {
    JIrcRobot jir = new JIrcRobot();
    jir.loadPlugins("plugins");
    if (jir.connect()) {
        jir.run();
    }
}

Rien de complexe : on créé un objet JIrcRobot, on charge les plugins, on connecte le robot au serveur IRC, et enfin on se met en attente de réception des messages avec la méthode run(). Il est maintenant temps de voir comment sont chargés les plugins, avec la méthode loadPlugins ;

public void loadPlugins(String folder) {
    ScriptEngine engine;
    Invocable inv;
    File dir = new File(folder);
    for (File file : dir.listFiles()) {
        if (file.isFile() && file.getName().toLowerCase().endsWith(".js")) {
            try {
                engine = new ScriptEngineManager().getEngineByName("JavaScript");
                engine.put("robot", this);
                engine.eval(new FileReader(file.getAbsolutePath()));
                inv = (Invocable) engine;
                this.plugins.add(inv.getInterface(Plugin.class));
                System.out.println(file.getAbsolutePath() + " loaded.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Cette méthode va lister (listFiles) le dossier dont le nom lui est passé en paramètre (folder). Pour chaque fichier dont l'extension est .js (endsWith), elle créé un moteur de JavaScript (getEngineByName) et place dans l'environnement du script une variable nommée robot pointant sur l'objet JIrcRobot (put). Ensuite elle lit le contenu du fichier et stocke dans le tableau plugins une instanciation de l'interface Plugin provenant du fichier (getInterface).

Le chargement des plugins consiste donc à stocker des objets implémentant l'interface Plugin et dont le contenu provient des fichiers JavaScript.

Maintenant, la méthode run :

public void run() {
    String buffer;
    Matcher matcher;
    while (this.stayConnected) {
        buffer = this.readLine();
        if (!buffer.equals("")) {
            System.out.println(buffer);
            for (Plugin p : this.plugins) {
                matcher = Pattern.compile(p.getPattern()).matcher(buffer);
                if (matcher.find()) {
                    p.patternMatch(matcher);
                }
            }
        }
    }
}

Cette méthode contient une boucle qui attend un message du serveur IRC (readLine). Une fois qu'un message est reçu, elle boucle sur tous les plugins chargés. Pour chacun d'eux, elle teste si le pattern du plugin (p.getPattern()) match avec le message reçu (buffer). Si c'est le cas (find), la méthode patterMatch() du plugin est appellée et on lui passe en paramètre le matcher, ce qui permettra au plugin d'analyser les groupes capturés grâce à l'expression régulière. C'est assez pratique car le plugin reçoit ainsi seulement ce qui l'intéresse, et qu'il a lui-même spécifié dans la regex.

C'est ici que s'arrête le détail ! Nous avons un système qui stocke des plugins et un autre qui communique avec eux pour savoir s'il faut les solliciter (grâce à un système de regex ici, mais ca pourrait être autrement) et qui qui les exécute si besoin. Ce robot IRC est donc ainsi fait d'un noyau, disposant de peu de fonctionnalités, mais extensible à volonté.

Les plugins

Notre programme étant prêt, concentrons nous maintenant sur les plugins. Nous créerons un fichier par plugin

ping.js

Le serveur IRC envoie régulièrement un message PING auquel le client doit répondre. Si la réponse n'est pas envoyée dans un certain laps de temps, le serveur rompt la connexion. Ce plugin est donc vital. Le message est du type "PING :msg". Le client doit répondre "PONG :msg". msg est parfois le nom du serveur, ou parfois un numéro aléatoire. Pour un PING reçu, on récupèrera donc la partie droite, et on s'en servira pour envoyer le PONG. Voici le contenu de ping.js :

importClass(java.util.regex.Matcher);

function getPattern() {
    return 'PING\\s:(.*)';
}

function patternMatch(matcher) {
    robot.write("PONG :" + matcher.group(1));
}

On commence par importer la classe Java Matcher. On implémente ensuite les deux méthodes nécessaires de l'interface Plugin. Le regex renvoyé par getPattern contient un groupe qui capturera la partie à renvoyer par le PONG. La fonction patternMatch qui est appelée si le regex a matché envoie le PONG suivi du groupe capturé dans le PING. Pour cela elle utilise la variable robot représentant l'objet JIrcRobot pour envoyer un message au serveur.

endOfMOTD.js

Le Message Of The Day (MOTD) est un texte envoyé par le serveur au client lorsqu'il se connecte. Il contient souvent des informations sur le serveur. Une fois le MOTD envoyé, le serveur envoie un message indiquant la fin du MOTD du type : ":calvino.freenode.net 376 jircrobot :End of /MOTD command.". Il est important de réagir à ce message car certains serveurs n'autorisent pas le client à rejoindre des canaux tant que le MOTD n'a pas été envoyé. En attendant la réception de ce message pour rejoindre des canaux, on est sûr qu'on ne sera pas bloqué. Ce plugin réagira donc à ce message, et une fois reçu, appellera la méthode joinChannels de la classe JIrcRobot :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':.*\\s376\\s.*';
}

function patternMatch(matcher) {
    robot.joinChannels();
}

C'est assez simple ici encore. On donne la regex pour capturer la fin du MOTD et lorsque que le message est arrivé, on utilise la variable robot pour se connecter aux canaux.

quit.js

Ce plugin permettra de stopper le bot. Lorsqu'une personne tapera !QUIT sur un canal, le robot se stoppera. Biensûr dans le cadre d'un "vrai" bot, il faudrait s'assurer que la personne voulant couper le robot en a le droit, en se basant sur son nom d'hôte ou son pseudonyme. Le message envoyé par le serveur sera du type ":someone!~someident@some-host.com PRIVMSG #channel1 :!QUIT". Voici le contenu du plugin :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':.*\\sPRIVMSG\\s[^ ]+\\s:!QUIT';
}

function patternMatch(matcher) {
    robot.setStayConnected(false);
}

La regex ne capture rien ici car on ne gère pas de droits. Pour quelque chose de plus sécurisé, il faudrait capturer au moins le pseudonyme de la personne. La fonction appelée utilisera la méthode setStayConnected avec false en paramètre, ce qui aura pour effet de stopper la méthode run du robot.

join.js

Afin de rendre notre robot un minimum sociable, ce plugin aura pour tâche de le faire se présenter lorsqu'il rejoint un canal et de souhaiter la bienvenue aux nouveaux arrivants. Pour cela, il suffira de capturer les messages de type JOIN provenant du serveur, qui sont envoyés quand une personne rejoint un canal, ou quand le bot lui même le fait. Le message est du type ":nick!~ident@hostname.fr JOIN :#channel". Il suffit alors de comparer "nick" avec le propre pseudonyme du robot. S'il sont équivalents, c'est que c'est lui qui entre sur un canal, il doit donc se présenter. Si ce n'est pas le sien, alors il souhaite la bienvenue au nouvel arrivant. Il faudra donc capturer le pseudonyme et le nom du canal afin de s'en servir pour envoyer le message :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':([^!]+).*\\sJOIN\\s:([^ ]+)';
}

function patternMatch(matcher) {
    // Si c'est le robot qui JOIN
    if(matcher.group(1) == robot.getNickname()) {
        robot.write("PRIVMSG "+matcher.group(2)+" :Salut tout le monde, je suis "+matcher.group(1));
    }
    else { // si c'est un nouvel arrivant
        robot.write("PRIVMSG "+matcher.group(2)+" :Salut "+matcher.group(1));
    }
}

On voit donc la regex avec les deux captures (nick + canal). Ces informations sont ensuite utilisées pour le message envoyé.

patriote.js

Un plugin beaucoup moins utile, qui permettra simplement de montrer comment réagir à un texte particulier. Nous souhaitons ici que le bot montre qu'il est fier d'être français. A chaque fois que le mot France (peu importe la casse) sera écrit, il réagira. Le message reçu sera du type ":someone!~someident@some-host.com PRIVMSG #channel :Vive la France". Voyons le code du plugin :

importClass(java.util.regex.Matcher);

function getPattern() {
    return '(?i):[^!]+.*\\sPRIVMSG\\s([^ ]+)\\s:.*france.*';
}

function patternMatch(matcher) {
    robot.write("PRIVMSG "+matcher.group(1)+" :COCORICO !!!");
}

La regex indique que la recherche sera insensible à la casse. On capture simplement le nom du canal d'où le texte est envoyé pour pouvoir répondre.


Voilà pour quelques exemples de plugins. Le but ici est de montrer que presque tout est possible, mais que surtout ce genre de programme, modulable, auquel on peut ajouter des fonctionnalités, est facilement réalisable. Pour les plus courageux qui auront lu jusque ici (j'espère que number80 en fait partie !), n'hésitez pas à poser des questions dans les commentaires. Il n'est pas facile de synthétiser tout cela en un seul billet, il y a donc probablement des passages obscurs !


Fabien (eponyme)

Scripts JS avec Java et Rhino : mise en œuvre avec un bot IRC

Fabien Nicoleau

Je montrais dans mon billet précédent que grâce à Rhino il est possible d'exécuter du code JavaScript depuis un programme Java, et comment il possible de se servir de ce système pour gérer des plugins. Je propose dans ce billet de mettre en œuvre ces fonctionnalités et de les appliquer à un projet simple : un robot IRC modulaire. Le principe est d'avoir un robot écrit en Java et capable de se connecter à un serveur IRC, puis de communiquer avec lui (envoi et réception de messages). Nous n'ajouterons rien à ce programme Java, aucun savoir faire pour ce robot, à une exception prêt : la possibilité de stocker des plugins qui lui permettront d'avoir de nouvelles fonctionnalités. Attention, le sujet de ce billet n'étant pas le codage d'un robot IRC (il y en a de meilleurs pour ca ^^), celui présenté ici est ultra simple, et se contente du minimum.

Pour comprendre ce programme, il faut avoir quelques notions sur Rhino/Java, des notions sur les expressions régulières, et notamment les groups qui seront bien utiles ici, et savoir en gros ce qu'est un client IRC.

Le décor

Le programme sera donc codé en Java. Une classe JIrcRobot se chargera de se connecter au serveur IRC, et de communiquer avec lui. Une interface permettra de définir les méthodes à implémenter par les plugins. Elle sera originalement nommée Plugin. La classe JIrcRobot chargera les plugins disponibles, c'est à dire ceux contenus dans le dossier originalement nommé plugins et dont l'extension est .js, puisqu'ils contiennent du code JavaScript. Cela permettra aussi de pouvoir désactiver le chargement d'un plugin en modifiant simplement son extension. Une fois les plugins chargés, le programme attendra des messages du serveur. A chaque message reçu, il interrogera tout ses plugins pour savoir si l'un d'eux est concerné par le message. Si c'est le cas, le plugin sera alors exécuté et pourra alors réagir en envoyant des messages au serveur IRC.

Le test

Pour ceux qui préfèrent voir les choses fonctionner tout de suite, et voir comment ca marche, je vous propose de tester tout de suite le programme. Il vous faut récupérer tous les fichiers en annexe de ce programme : le fichier JIrcRobot.java ainsi que tous les fichiers en .js, qui seront à mettre dans un dossier nommé plugins. JIrcRobot.java sera à mettre au même niveau d'arborescence que le dossier plugins. Vous pouvez sinon juste prendre le fichier jircrobot.tar.gz et le décompresser.

Ouvrez ensuite le fichier JIrcRobot.java et éditez les paramètres de connexion, situés sous le commentaire "CONFIGURATION DE LA CONNEXION AU SERVEUR" pour donner un pseudonyme au robot, lui indiquer sur quel serveur il doit se connecter, et quels canaux il doit rejoindre. Sauvegardez les modifications et compilez le programme :

javac JIrcRobot.java

Vous pouvez maintenant l'exécuter :

java JIrcRobot

Le robot charge les plugins puis se connecte au serveur. En l'état actuel, le robot est capable de répondre aux PING du serveur, afin qu'il ne coupe pas la connexion, de rejoindre des canaux de discussion, de se présenter quand il rejoint un canal et souhaiter la bienvenue à ceux qui arrivent ensuite, de se couper si quelqu'un tape "!QUIT" et enfin de crier "COCORICO" si une phrase contient "france". Ces fonctionnalités sont toutes apportées par les plugins. Le programme Java en lui même ne sait rien faire de tout ca.

La classe JIrcRobot

Il est maintenant temps de comprendre comment tout cela fonctionne. Je passe rapidement sur les fonctionnalités liées au protocole IRC. Sans entrer dans le code, il faut juste savoir que la classe propose ces méthodes :

connect() : se connecte au serveur IRC
getNickName() : renvoie le pseudonyme du robot
joinChannels() : envoie les commandes au serveur IRC pour rejoindre des canaux de discussion
loadPlugins() : charge tous les plugins disponibles dans un dossier
readLine() : lis un message provenant du serveur, s'il y en a un d'arrivé
run() : boucle conservant la connexion avec le serveur, et exécutant les plugins si besoin
setStayConnected() : permet d'indiquer si l'on souhaite rester connecté au serveur ou non
write() : envoi un message au serveur IRC


Les méthodes importantes seront détaillées ensuite : loadPlugins et run.

Enfin la classe contient une interface privée, Plugin, qui permet de définir les méthodes que devront implémenter les plugins :

getPattern() : retournera l'expression régulière qui si elle est validée, indiquera que le plugin doit réagir au message arrivé
patternMatch() : cette méthode sera appelée si l'expression régulière du plugin match avec le message arrivé

Nos plugins devront donc implémenter ces deux méthodes.

Le programme Java

Après avoir vu les méthodes permettant de dialoguer avec le serveur, intéressons nous, dans le détail cette fois-ci, au code des deux principales. Avant cela, un rapide coup d'œil à la méthode main du programme :

public static void main(String[] args) {
    JIrcRobot jir = new JIrcRobot();
    jir.loadPlugins("plugins");
    if (jir.connect()) {
        jir.run();
    }
}

Rien de complexe : on créé un objet JIrcRobot, on charge les plugins, on connecte le robot au serveur IRC, et enfin on se met en attente de réception des messages avec la méthode run(). Il est maintenant temps de voir comment sont chargés les plugins, avec la méthode loadPlugins ;

public void loadPlugins(String folder) {
    ScriptEngine engine;
    Invocable inv;
    File dir = new File(folder);
    for (File file : dir.listFiles()) {
        if (file.isFile() && file.getName().toLowerCase().endsWith(".js")) {
            try {
                engine = new ScriptEngineManager().getEngineByName("JavaScript");
                engine.put("robot", this);
                engine.eval(new FileReader(file.getAbsolutePath()));
                inv = (Invocable) engine;
                this.plugins.add(inv.getInterface(Plugin.class));
                System.out.println(file.getAbsolutePath() + " loaded.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Cette méthode va lister (listFiles) le dossier dont le nom lui est passé en paramètre (folder). Pour chaque fichier dont l'extension est .js (endsWith), elle créé un moteur de JavaScript (getEngineByName) et place dans l'environnement du script une variable nommée robot pointant sur l'objet JIrcRobot (put). Ensuite elle lit le contenu du fichier et stocke dans le tableau plugins une instanciation de l'interface Plugin provenant du fichier (getInterface).

Le chargement des plugins consiste donc à stocker des objets implémentant l'interface Plugin et dont le contenu provient des fichiers JavaScript.

Maintenant, la méthode run :

public void run() {
    String buffer;
    Matcher matcher;
    while (this.stayConnected) {
        buffer = this.readLine();
        if (!buffer.equals("")) {
            System.out.println(buffer);
            for (Plugin p : this.plugins) {
                matcher = Pattern.compile(p.getPattern()).matcher(buffer);
                if (matcher.find()) {
                    p.patternMatch(matcher);
                }
            }
        }
    }
}

Cette méthode contient une boucle qui attend un message du serveur IRC (readLine). Une fois qu'un message est reçu, elle boucle sur tous les plugins chargés. Pour chacun d'eux, elle teste si le pattern du plugin (p.getPattern()) match avec le message reçu (buffer). Si c'est le cas (find), la méthode patterMatch() du plugin est appellée et on lui passe en paramètre le matcher, ce qui permettra au plugin d'analyser les groupes capturés grâce à l'expression régulière. C'est assez pratique car le plugin reçoit ainsi seulement ce qui l'intéresse, et qu'il a lui-même spécifié dans la regex.

C'est ici que s'arrête le détail ! Nous avons un système qui stocke des plugins et un autre qui communique avec eux pour savoir s'il faut les solliciter (grâce à un système de regex ici, mais ca pourrait être autrement) et qui qui les exécute si besoin. Ce robot IRC est donc ainsi fait d'un noyau, disposant de peu de fonctionnalités, mais extensible à volonté.

Les plugins

Notre programme étant prêt, concentrons nous maintenant sur les plugins. Nous créerons un fichier par plugin

ping.js

Le serveur IRC envoie régulièrement un message PING auquel le client doit répondre. Si la réponse n'est pas envoyée dans un certain laps de temps, le serveur rompt la connexion. Ce plugin est donc vital. Le message est du type "PING :msg". Le client doit répondre "PONG :msg". msg est parfois le nom du serveur, ou parfois un numéro aléatoire. Pour un PING reçu, on récupèrera donc la partie droite, et on s'en servira pour envoyer le PONG. Voici le contenu de ping.js :

importClass(java.util.regex.Matcher);

function getPattern() {
    return 'PING\\s:(.*)';
}

function patternMatch(matcher) {
    robot.write("PONG :" + matcher.group(1));
}

On commence par importer la classe Java Matcher. On implémente ensuite les deux méthodes nécessaires de l'interface Plugin. Le regex renvoyé par getPattern contient un groupe qui capturera la partie à renvoyer par le PONG. La fonction patternMatch qui est appelée si le regex a matché envoie le PONG suivi du groupe capturé dans le PING. Pour cela elle utilise la variable robot représentant l'objet JIrcRobot pour envoyer un message au serveur.

endOfMOTD.js

Le Message Of The Day (MOTD) est un texte envoyé par le serveur au client lorsqu'il se connecte. Il contient souvent des informations sur le serveur. Une fois le MOTD envoyé, le serveur envoie un message indiquant la fin du MOTD du type : ":calvino.freenode.net 376 jircrobot :End of /MOTD command.". Il est important de réagir à ce message car certains serveurs n'autorisent pas le client à rejoindre des canaux tant que le MOTD n'a pas été envoyé. En attendant la réception de ce message pour rejoindre des canaux, on est sûr qu'on ne sera pas bloqué. Ce plugin réagira donc à ce message, et une fois reçu, appellera la méthode joinChannels de la classe JIrcRobot :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':.*\\s376\\s.*';
}

function patternMatch(matcher) {
    robot.joinChannels();
}

C'est assez simple ici encore. On donne la regex pour capturer la fin du MOTD et lorsque que le message est arrivé, on utilise la variable robot pour se connecter aux canaux.

quit.js

Ce plugin permettra de stopper le bot. Lorsqu'une personne tapera !QUIT sur un canal, le robot se stoppera. Biensûr dans le cadre d'un "vrai" bot, il faudrait s'assurer que la personne voulant couper le robot en a le droit, en se basant sur son nom d'hôte ou son pseudonyme. Le message envoyé par le serveur sera du type ":someone!~someident@some-host.com PRIVMSG #channel1 :!QUIT". Voici le contenu du plugin :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':.*\\sPRIVMSG\\s[^ ]+\\s:!QUIT';
}

function patternMatch(matcher) {
    robot.setStayConnected(false);
}

La regex ne capture rien ici car on ne gère pas de droits. Pour quelque chose de plus sécurisé, il faudrait capturer au moins le pseudonyme de la personne. La fonction appelée utilisera la méthode setStayConnected avec false en paramètre, ce qui aura pour effet de stopper la méthode run du robot.

join.js

Afin de rendre notre robot un minimum sociable, ce plugin aura pour tâche de le faire se présenter lorsqu'il rejoint un canal et de souhaiter la bienvenue aux nouveaux arrivants. Pour cela, il suffira de capturer les messages de type JOIN provenant du serveur, qui sont envoyés quand une personne rejoint un canal, ou quand le bot lui même le fait. Le message est du type ":nick!~ident@hostname.fr JOIN :#channel". Il suffit alors de comparer "nick" avec le propre pseudonyme du robot. S'il sont équivalents, c'est que c'est lui qui entre sur un canal, il doit donc se présenter. Si ce n'est pas le sien, alors il souhaite la bienvenue au nouvel arrivant. Il faudra donc capturer le pseudonyme et le nom du canal afin de s'en servir pour envoyer le message :

importClass(java.util.regex.Matcher);

function getPattern() {
    return ':([^!]+).*\\sJOIN\\s:([^ ]+)';
}

function patternMatch(matcher) {
    // Si c'est le robot qui JOIN
    if(matcher.group(1) == robot.getNickname()) {
        robot.write("PRIVMSG "+matcher.group(2)+" :Salut tout le monde, je suis "+matcher.group(1));
    }
    else { // si c'est un nouvel arrivant
        robot.write("PRIVMSG "+matcher.group(2)+" :Salut "+matcher.group(1));
    }
}

On voit donc la regex avec les deux captures (nick + canal). Ces informations sont ensuite utilisées pour le message envoyé.

patriote.js

Un plugin beaucoup moins utile, qui permettra simplement de montrer comment réagir à un texte particulier. Nous souhaitons ici que le bot montre qu'il est fier d'être français. A chaque fois que le mot France (peu importe la casse) sera écrit, il réagira. Le message reçu sera du type ":someone!~someident@some-host.com PRIVMSG #channel :Vive la France". Voyons le code du plugin :

importClass(java.util.regex.Matcher);

function getPattern() {
    return '(?i):[^!]+.*\\sPRIVMSG\\s([^ ]+)\\s:.*france.*';
}

function patternMatch(matcher) {
    robot.write("PRIVMSG "+matcher.group(1)+" :COCORICO !!!");
}

La regex indique que la recherche sera insensible à la casse. On capture simplement le nom du canal d'où le texte est envoyé pour pouvoir répondre.


Voilà pour quelques exemples de plugins. Le but ici est de montrer que presque tout est possible, mais que surtout ce genre de programme, modulable, auquel on peut ajouter des fonctionnalités, est facilement réalisable. Pour les plus courageux qui auront lu jusque ici (j'espère que number80 en fait partie !), n'hésitez pas à poser des questions dans les commentaires. Il n'est pas facile de synthétiser tout cela en un seul billet, il y a donc probablement des passages obscurs !


Fabien (eponyme)

mysql-5.1.53

Remi Collet

Les RPM de MySQL Community Server 5.1.53 GA sont disponibles dans le dépôt remi pour RHEL, CentOS et Fedora. Voir le Changelog.

Cette construction utilise un fichier .spec proche de celui de Rawhide.  Le nouveau plugin InnoDB (version 1.0.12 GA) est aussi disponible, le fichier de configuration (/etc/my.cnf) contient les options pour l'active (sauf pour EL-4) ATTENTION : avant la mise à jour, une sauvegarde de vos bases de données est très vivement conseillée (un vidage... Lire mysql-5.1.53

Java : gérer facilement des plugins JavaScript

Fabien Nicoleau

Dans une application, il peut être parfois intéressant d'extraire une partie de l'intelligence afin de répondre à un besoins sépcifique. Un exemple courant est une application fournie à différents clients. Elle comporte un socle commun, puis les spécificités sont développées dans des plugins afin de ne pas avoir à toucher au code de l'application pour une demande particulière. L'autre intérêt est de pouvoir charger dans une application des fonctionnalités supplémentaires, permettant de réduire le poids de l'application en retirant des fonctionnalités inutilisées. Le fait d'avoir du code externe permet aussi d'en facilité les mises à jour.

En Java, il est possible de créer des plugins de différentes façons : avec des classes externes, chargées grâce à un ClassLoader, grâce à groovy, très populaire, ou encore jython, permettant d'exécuter du code Python depuis un programme Java. Il existe de nombreuses autres solutions, comme celle d'utiliser le moteur JavaScript de la fondation Mozilla : Rhino. Sa particularité est qu'il est fourni par défaut avec Java depuis la version 6.

En ayant eu besoin pour un projet, et ayant trouvé peu d'aide en français, je propose ici quelques exemples très basiques afin de mettre en place un système de plugins JavaScript avec Java. 90% de l'aide dont j'ai eu besoin a été trouvée sur cette page de documentation. Je reprends donc ici quelques exemples, commentés, afin de comprendre le principe et d'imaginer les possibilités qu'offre Rhino. N'hésitez pas à poser des questions dans les commentaires si vous avez besoins de précisions.

Tout d'abord, je vous indique ici les import dont vous aurez besoin et qui seront à utiliser tout au long des exemples (mais pas utiles pour tous). Il ne seront pas réécris ensuite, pour plus de lisibilité :

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

Toujours pour simplifier le code affiché, les exceptions ne seront pas gérées, mais renvoyées par le main. Il vous faut évidemment avoir quelques bases de Java et de JavaScript pour pouvoir suivre ces exemples. Dans chacun d'eux, j'utiliserai des fonctions JavaScript. Si vous préférez utiliser du code orienté objet, il vous sera facile de l'adapter grâce aux exemples de la page Oracle citée en préambule.

Enfin, pour chaque exemple, je n'afficherai que la fonction main, qu'il faudra évidemment que vous incluiez dans une classe pour que le tout fonctionne, cependant les sources de chaque exemples sont disponibles en annexe de ce billet.

Exemple 1 : un simple affichage

Pour le premier essai, nous allons exécuter une simple ligne de code JavaScript dans du code Java :

public static void main(String[] args) throws Exception {
     ScriptEngineManager manager = new ScriptEngineManager();
     ScriptEngine engine = manager.getEngineByName("JavaScript");
     engine.eval("println('Mon premier script !');");
}

Rien de plus ! C'est en fait assez simple. Nous commençons par instancier un ScriptEngineManager qui nous permettra de charger le moteur de script souhaité. Nous l'utilisons sur la deuxième ligne : nous chargeons le moteur JavaScript. Aucune installation de bibliothèque nécessaire, car ce moteur est fourni avec Java 6 ! Ces deux premières lignes seront utilisées dans tous nos exemples. Nous terminons en demandant à notre moteur d'évaluer une ligne de code, ici l'affichage du texte "Mon premier script !".

Après compilation et exécution, la ligne s'affiche bien. Rien de transcendant ici, mais nous voyons que nous allons facilement pouvoir exécuter du code JavaScript.

Exemple 2 : interagir avec un script externe

Dans l'optique d'utiliser un système de plugins, il nous faut d'abord pouvoir sortir le code JavaScript du code Java, et le placer dans un fichier externe. De plus il nous faut pouvoir appeler une fonction en lui passant des paramètres, puis pouvoir récupérer le résultat obtenu.

Pour illustrer l'exemple, nous allons imaginer un programme Java qui passe à une fonction nommée compute() deux chiffres qu'elle traitera. Le code Java récupèrera le résultat du traitement effectué par compute() et l'affichera. Enfin, nous allons créer deux plugins JavaScript qui implémenteront tous les deux la fonction compute(). L'un fera une addition (plus.js) des deux chiffres donnés, l'autre une soustraction (moins.js). On commence par le code Java :

public static void main(String[] args) throws Exception {
     ScriptEngineManager manager = new ScriptEngineManager();
     ScriptEngine engine = manager.getEngineByName("JavaScript");
     engine.eval(new FileReader("plus.js"));
     Invocable inv = (Invocable) engine;
     System.out.println(inv.invokeFunction("compute",3,2));
}

Comme dans le premier exemple, nous récupérons le moteur JavaScript. Ensuite plutôt que directement évaluer du code, nous passons un fichier à la fonction eval(), qui contiendra notre code JavaScript. Nous commençons ici par plus.js, qui fera une addition. Vous pourrez ensuite utiliser moins.js. Enfin, nous invoquons la fonction compute() et lui passons deux arguments (3 et 2). Nous récupérons le résultat du traitement, qui est un Object, et qui contiendra ici un chiffre (un Double à vrai dire), nous l'affichons directement.

Voici le contenu de plus.js :

function compute(a,b) {
   return a+b;
}

Celui de moin.js :

function compute(a,b) {
   return a-b;
}

Aucun commentaire nécessaire ! Exécutez le programme avec plus.js, puis moins.js, les résultats seront 5.0 puis 1.0.

Nous voyons ici que nous pouvons très facilement avoir du code Java qui exécute une fonction dont il ne connait pas le contenu. Il en récupère le résultat sous forme d'un objet et peut le traiter. D'un autre coté, nous avons des fichiers contenant du code JavaScript qui traitent de façon différente deux arguments identiques, et renvoient le résultat. Dans une application gérant des plugins, il suffit alors que le nom du fichier JavaScript soit une variable, ou provienne d'un choix de l'utilisateur, et le tour est joué ! Attention tout de même, pour un système robuste, il est important de gérer les exceptions afin de réagir aux problèmes qui pourraient survenir.

Exemple 3 : Exporter des variables dans le script externe

Lorsque l'on mets en place un système de plugins, on souhaite que ces derniers puissent avoir accès aux informations de l'application, souvent par l'intermédiaire d'un noyau depuis lequel on accède à des variables. De cette manière le plugin agit de façon directe avec l'application, en consultant des informations, et en les mettant à jour. Nous allons dans cet exemple voir qu'il est tout à fait possible de faire cela avec Java et Rhino. Nous allons créer une classe Afficheur contenant la méthode affiche() qui se contente d'afficher dans la console une ligne de texte. Ensuite, nous allons instancier un objet de cette classe et l'exporter dans notre script JavaScript. Ce dernier utilisera dans son code l'objet exporté et appellera la méthode affiche() :

private static class Afficheur {
   public void affiche() {
       System.out.println("J'affiche !");
    }
}
public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval(new FileReader("afficheur.js"));
    Afficheur aff = new Afficheur();
    engine.put("monAfficheur",aff);
    Invocable inv = (Invocable) engine;
    inv.invokeFunction("affiche");
}

On voit ici qu'une fois l'objet Afficheur instancié, on l'exporte dans le script grace à la méthode put(). On indique que le nom de variable par laquelle l'objet sera accessible dans le script sera "monAfficheur". Enfin on appelle la fonction affiche() implémentée dans le script afficheur.js dont voici le contenu :

function affiche() {
   monAfficheur.affiche();
}

La fonction affiche() utilise donc la variable monAfficheur disponnible grace à l'export fait depuis le code Java, et appelle la méthode affiche(). Voilà notre liaison réalisée ! Depuis notre code JavaScript, nous accédons à un objet de notre application Java et pouvons l'utiliser. Ici nous ne réalisons qu'un simple affichage, mais tout est possible. Notez qu'il est possible de définir différent scope lors de l'export des variables permettant ainsi de leur donner des valeurs différentes selon le contexte utilisé lors de l'évaluation. Plus de renseignement dans la documentation.

Exemple 4 : Implémenter une interface

Nous progressons dans les fonctionnalités proposées pour réaliser une gestion de plugins. Mais il est possible d'aller plus loin, et de définir plus précisément les fonctionnalités offertes par les plugins. Pour cela, nous pouvons définir en Java une interface, et l'implémenter depuis un plugin. Une fois le code du plugin évalué, nous appelons une méthode depuis le code Java, dont l'implémentation a été réalisée depuis le code JavaScript ! Il devient alors possible de définir proprement en Java les méthodes qui seront à implémenter par les plugins, sans en connaitre le traitement évidemment, et d'utiliser ensuite dans le code des objets instanciant cette interface. Mieux que du blabla, le code : 

private interface Afficheur2 {
    void affiche2();
}
public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval("function affiche2() { println('affiche (2)'); }");
    Invocable inv = (Invocable) engine;
    Afficheur2 aff = inv.getInterface(Afficheur2.class);
    aff.affiche2();
}

Pour l'exemple, je n'utilise pas de fichier externe, mais directement une ligne de code JavaScript. Ce code implémente la méthode affiche2() de l'interface Afficheur2 en faisant un simple affichage de ligne. Nous créons un objet de type Afficheur2 puis récupérons l'instanciation de l'interface grâce à la méthode getInterface().

Enfin, nous utilisons ce nouvel objet et appelons la méthode affiche2() qui effectuera ce qui a été défini dans le code JavaScript, c'est à dire afficher une ligne de texte.

Nous voyons ici qu'il nous est donc possible d'écrire du code générique et de l'utiliser. C'est grâce aux plugins utilisés que instanciation est faite et nous pouvons ainsi pour un même code Java obtenir des comportement totalement différents.

Exemple 5 : Utilisation des classes Java depuis le code JavaScript

Comme dernier exemple et pour montrer toute la puissance de Rhino, nous créons un code Java qui se contentera d'évaluer un script :

public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval(new FileReader("frame.js"));
}

Le script en revanche est particulier, car il importe directement des classes Java et utilise les objets instanciés. Le script frame.js va créer une JFrame et l'afficher. Il affichera aussi le titre de la fenêtre, qu'il récupère directement depuis la propriété de la JFrame :

importClass(javax.swing.JFrame);
importClass(java.awt.Dimension);

var frame = new JFrame("hello");
frame.setSize(new Dimension(250,250));
frame.setVisible(true);
println(frame.title);

Exécutez le programme, une fenêtre apparait !

JFrame depuis un JavaScript


Voilà pour cette petite initiation au scripting avec Java et son application avec l'utilisation de plugins. Il y aurait surement beaucoup plus à dire, mais vous disposez maintenant d'une base pour débuter, et de l'alliance du Java et du JavaScript pour vos applications ! Ce sujet aura aussi été pour moi l'occasion de reprendre la plume sur ce blog, chose qui n'avait pas été faite depuis trop longtemps !


Fabien (eponyme)

Java : gérer facilement des plugins JavaScript

Fabien Nicoleau

Dans une application, il peut être parfois intéressant d'extraire une partie de l'intelligence afin de répondre à un besoins sépcifique. Un exemple courant est une application fournie à différents clients. Elle comporte un socle commun, puis les spécificités sont développées dans des plugins afin de ne pas avoir à toucher au code de l'application pour une demande particulière. L'autre intérêt est de pouvoir charger dans une application des fonctionnalités supplémentaires, permettant de réduire le poids de l'application en retirant des fonctionnalités inutilisées. Le fait d'avoir du code externe permet aussi d'en facilité les mises à jour.

En Java, il est possible de créer des plugins de différentes façons : avec des classes externes, chargées grâce à un ClassLoader, grâce à groovy, très populaire, ou encore jython, permettant d'exécuter du code Python depuis un programme Java. Il existe de nombreuses autres solutions, comme celle d'utiliser le moteur JavaScript de la fondation Mozilla : Rhino. Sa particularité est qu'il est fourni par défaut avec Java depuis la version 6.

En ayant eu besoin pour un projet, et ayant trouvé peu d'aide en français, je propose ici quelques exemples très basiques afin de mettre en place un système de plugins JavaScript avec Java. 90% de l'aide dont j'ai eu besoin a été trouvée sur cette page de documentation. Je reprends donc ici quelques exemples, commentés, afin de comprendre le principe et d'imaginer les possibilités qu'offre Rhino. N'hésitez pas à poser des questions dans les commentaires si vous avez besoins de précisions.

Tout d'abord, je vous indique ici les import dont vous aurez besoin et qui seront à utiliser tout au long des exemples (mais pas utiles pour tous). Il ne seront pas réécris ensuite, pour plus de lisibilité :

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

Toujours pour simplifier le code affiché, les exceptions ne seront pas gérées, mais renvoyées par le main. Il vous faut évidemment avoir quelques bases de Java et de JavaScript pour pouvoir suivre ces exemples. Dans chacun d'eux, j'utiliserai des fonctions JavaScript. Si vous préférez utiliser du code orienté objet, il vous sera facile de l'adapter grâce aux exemples de la page Oracle citée en préambule.

Enfin, pour chaque exemple, je n'afficherai que la fonction main, qu'il faudra évidemment que vous incluiez dans une classe pour que le tout fonctionne, cependant les sources de chaque exemples sont disponibles en annexe de ce billet.

Exemple 1 : un simple affichage

Pour le premier essai, nous allons exécuter une simple ligne de code JavaScript dans du code Java :

public static void main(String[] args) throws Exception {
     ScriptEngineManager manager = new ScriptEngineManager();
     ScriptEngine engine = manager.getEngineByName("JavaScript");
     engine.eval("println('Mon premier script !');");
}

Rien de plus ! C'est en fait assez simple. Nous commençons par instancier un ScriptEngineManager qui nous permettra de charger le moteur de script souhaité. Nous l'utilisons sur la deuxième ligne : nous chargeons le moteur JavaScript. Aucune installation de bibliothèque nécessaire, car ce moteur est fourni avec Java 6 ! Ces deux premières lignes seront utilisées dans tous nos exemples. Nous terminons en demandant à notre moteur d'évaluer une ligne de code, ici l'affichage du texte "Mon premier script !".

Après compilation et exécution, la ligne s'affiche bien. Rien de transcendant ici, mais nous voyons que nous allons facilement pouvoir exécuter du code JavaScript.

Exemple 2 : interagir avec un script externe

Dans l'optique d'utiliser un système de plugins, il nous faut d'abord pouvoir sortir le code JavaScript du code Java, et le placer dans un fichier externe. De plus il nous faut pouvoir appeler une fonction en lui passant des paramètres, puis pouvoir récupérer le résultat obtenu.

Pour illustrer l'exemple, nous allons imaginer un programme Java qui passe à une fonction nommée compute() deux chiffres qu'elle traitera. Le code Java récupèrera le résultat du traitement effectué par compute() et l'affichera. Enfin, nous allons créer deux plugins JavaScript qui implémenteront tous les deux la fonction compute(). L'un fera une addition (plus.js) des deux chiffres donnés, l'autre une soustraction (moins.js). On commence par le code Java :

public static void main(String[] args) throws Exception {
     ScriptEngineManager manager = new ScriptEngineManager();
     ScriptEngine engine = manager.getEngineByName("JavaScript");
     engine.eval(new FileReader("plus.js"));
     Invocable inv = (Invocable) engine;
     System.out.println(inv.invokeFunction("compute",3,2));
}

Comme dans le premier exemple, nous récupérons le moteur JavaScript. Ensuite plutôt que directement évaluer du code, nous passons un fichier à la fonction eval(), qui contiendra notre code JavaScript. Nous commençons ici par plus.js, qui fera une addition. Vous pourrez ensuite utiliser moins.js. Enfin, nous invoquons la fonction compute() et lui passons deux arguments (3 et 2). Nous récupérons le résultat du traitement, qui est un Object, et qui contiendra ici un chiffre (un Double à vrai dire), nous l'affichons directement.

Voici le contenu de plus.js :

function compute(a,b) {
   return a+b;
}

Celui de moin.js :

function compute(a,b) {
   return a-b;
}

Aucun commentaire nécessaire ! Exécutez le programme avec plus.js, puis moins.js, les résultats seront 5.0 puis 1.0.

Nous voyons ici que nous pouvons très facilement avoir du code Java qui exécute une fonction dont il ne connait pas le contenu. Il en récupère le résultat sous forme d'un objet et peut le traiter. D'un autre coté, nous avons des fichiers contenant du code JavaScript qui traitent de façon différente deux arguments identiques, et renvoient le résultat. Dans une application gérant des plugins, il suffit alors que le nom du fichier JavaScript soit une variable, ou provienne d'un choix de l'utilisateur, et le tour est joué ! Attention tout de même, pour un système robuste, il est important de gérer les exceptions afin de réagir aux problèmes qui pourraient survenir.

Exemple 3 : Exporter des variables dans le script externe

Lorsque l'on mets en place un système de plugins, on souhaite que ces derniers puissent avoir accès aux informations de l'application, souvent par l'intermédiaire d'un noyau depuis lequel on accède à des variables. De cette manière le plugin agit de façon directe avec l'application, en consultant des informations, et en les mettant à jour. Nous allons dans cet exemple voir qu'il est tout à fait possible de faire cela avec Java et Rhino. Nous allons créer une classe Afficheur contenant la méthode affiche() qui se contente d'afficher dans la console une ligne de texte. Ensuite, nous allons instancier un objet de cette classe et l'exporter dans notre script JavaScript. Ce dernier utilisera dans son code l'objet exporté et appellera la méthode affiche() :

private static class Afficheur {
   public void affiche() {
       System.out.println("J'affiche !");
    }
}
public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval(new FileReader("afficheur.js"));
    Afficheur aff = new Afficheur();
    engine.put("monAfficheur",aff);
    Invocable inv = (Invocable) engine;
    inv.invokeFunction("affiche");
}

On voit ici qu'une fois l'objet Afficheur instancié, on l'exporte dans le script grace à la méthode put(). On indique que le nom de variable par laquelle l'objet sera accessible dans le script sera "monAfficheur". Enfin on appelle la fonction affiche() implémentée dans le script afficheur.js dont voici le contenu :

function affiche() {
   monAfficheur.affiche();
}

La fonction affiche() utilise donc la variable monAfficheur disponnible grace à l'export fait depuis le code Java, et appelle la méthode affiche(). Voilà notre liaison réalisée ! Depuis notre code JavaScript, nous accédons à un objet de notre application Java et pouvons l'utiliser. Ici nous ne réalisons qu'un simple affichage, mais tout est possible. Notez qu'il est possible de définir différent scope lors de l'export des variables permettant ainsi de leur donner des valeurs différentes selon le contexte utilisé lors de l'évaluation. Plus de renseignement dans la documentation.

Exemple 4 : Implémenter une interface

Nous progressons dans les fonctionnalités proposées pour réaliser une gestion de plugins. Mais il est possible d'aller plus loin, et de définir plus précisément les fonctionnalités offertes par les plugins. Pour cela, nous pouvons définir en Java une interface, et l'implémenter depuis un plugin. Une fois le code du plugin évalué, nous appelons une méthode depuis le code Java, dont l'implémentation a été réalisée depuis le code JavaScript ! Il devient alors possible de définir proprement en Java les méthodes qui seront à implémenter par les plugins, sans en connaitre le traitement évidemment, et d'utiliser ensuite dans le code des objets instanciant cette interface. Mieux que du blabla, le code : 

private interface Afficheur2 {
    void affiche2();
}
public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval("function affiche2() { println('affiche (2)'); }");
    Invocable inv = (Invocable) engine;
    Afficheur2 aff = inv.getInterface(Afficheur2.class);
    aff.affiche2();
}

Pour l'exemple, je n'utilise pas de fichier externe, mais directement une ligne de code JavaScript. Ce code implémente la méthode affiche2() de l'interface Afficheur2 en faisant un simple affichage de ligne. Nous créons un objet de type Afficheur2 puis récupérons l'instanciation de l'interface grâce à la méthode getInterface().

Enfin, nous utilisons ce nouvel objet et appelons la méthode affiche2() qui effectuera ce qui a été défini dans le code JavaScript, c'est à dire afficher une ligne de texte.

Nous voyons ici qu'il nous est donc possible d'écrire du code générique et de l'utiliser. C'est grâce aux plugins utilisés que instanciation est faite et nous pouvons ainsi pour un même code Java obtenir des comportement totalement différents.

Exemple 5 : Utilisation des classes Java depuis le code JavaScript

Comme dernier exemple et pour montrer toute la puissance de Rhino, nous créons un code Java qui se contentera d'évaluer un script :

public static void main(String[] args) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.eval(new FileReader("frame.js"));
}

Le script en revanche est particulier, car il importe directement des classes Java et utilise les objets instanciés. Le script frame.js va créer une JFrame et l'afficher. Il affichera aussi le titre de la fenêtre, qu'il récupère directement depuis la propriété de la JFrame :

importClass(javax.swing.JFrame);
importClass(java.awt.Dimension);

var frame = new JFrame("hello");
frame.setSize(new Dimension(250,250));
frame.setVisible(true);
println(frame.title);

Exécutez le programme, une fenêtre apparait !

JFrame depuis un JavaScript


Voilà pour cette petite initiation au scripting avec Java et son application avec l'utilisation de plugins. Il y aurait surement beaucoup plus à dire, mais vous disposez maintenant d'une base pour débuter, et de l'alliance du Java et du JavaScript pour vos applications ! Ce sujet aura aussi été pour moi l'occasion de reprendre la plume sur ce blog, chose qui n'avait pas été faite depuis trop longtemps !


Fabien (eponyme)

GLPI version 0.78.1 disponible

Remi Collet

GLPI (Gestionnaire Libre de Parc Informatique) version 0.78.1 est sortie. Lire l'Annonce. Les RPM sont disponibles dans le dépôt remi-test (Fedora ≥ 11 et EL).

 Actuellement dans le dépôt remi-test : glpi-0.78.1-1 glpi-appliances-1.6.0-1 glpi-dumpentity-1.2.0-1 glpi-loadentity-1.2.0-1 glpi-mass-ocs-import-1.4.1-1 glpi-pdf-0.7.0-1 glpi-reports-1.4.0-1 glpi-webservices-1.0.0-1 Vous êtes invités à tester ces versions sur un environnement spécifique avant de migrer en production et à remonter vos... Lire GLPI version 0.78.1 disponible

Fedora 14 vs Fedora 13 : comparaison des performances pour les versions 32 bits

Patrice Kadionik

Pour rappel, ma machine est équipée d'un Quad Core Intel Q6600 à 2,4 GHz avec 4 Go de RAM.

Je me suis limité au benchmark UnixBench qui fournit un indice global, ce qui me simplifiera la comparaison. La version UnixBench utilisée est la version 4.1.0.

Mon protocole de tests est le suivant :
  • Installation de Fedora 14 avec mise à jour version 32 bits avec le noyau Fedora 2.6.35.6-48.fc14.i686.
  • La machine est placée en niveau 3 (init 3).
  • 10 séries de tests avec UnixBench compilé sous Fedora 14 et exécuté sous Fedora 14 (noyau Fedora 2.6.35.6-48.fc14.i686).
  • 10 séries de tests avec UnixBench compilé sous Fedora 13 et exécuté sous Fedora 13 (noyau Fedora 2.6.33.6-147.fc13.i686).
Voici les résultats obtenus :

Fedora 14 version 32 bits :

Série 1 : 659.8
Série 2 : 673.2
Série 3 : 675.2
Série 4 : 663.2
Série 5 : 662.6
Série 6 : 665.7
Série 7 : 658.5
Série 8 : 666.8
Série 9 : 658.9
Série 10 : 663.6

Moyenne : 664,8

Fedora 13 version 32 bits :

Voici pour rappel les résultats obtenus avec Fedora 13 :
Série 1 : 686.6
Série 2 : 670.5
Série 3 : 685.4
Série 4 : 683.8
Série 5 : 690.0
Série 6 : 684.3
Série 7 : 674.3
Série 8 : 685.3
Série 9 : 684.7
Série 10 : 684.7

Moyenne : 683,0



Résultats :

Pour Fedora 14, on obtient un indice moyen de  664,8 pour UnixBench.
Pour Fedora 13, j'avais obtenu un indice moyen de 683,0 pour UnixBench.


On a donc une petite perte moyenne de près de 2,7 % de Fedora 14 32 bits par rapport à Fedora 13 32 bits...


Conclusion :


Au moment de ces tests, le noyau Fedora 14 (basé sur le noyau vanilla 2.6.35) accuse une légère baisse de 2,7 % non significative par rapport au noyau Fedora 13 (basé sur le noyau vanilla 2.6.33).


++

Facebook : bring back your shoes box !

Sébastien Natroll Une part de votre vie, une boîte pleine de souvenirs, bons ou mauvais…Facebook, nourri de milliers de statuts, retrace parfois l’existence d’une personne. Si vous voulez remonter le temps, suivez le guide ! Commencez par utiliser Facebook en anglais (US). Ensuite, allez à la page des paramètres du compte. Puis cliquer sur « Learn More » à La suite >

Facebook : bring back your shoes box !

Sébastien Natroll Une part de votre vie, une boîte pleine de souvenirs, bons ou mauvais…Facebook, nourri de milliers de statuts, retrace parfois l’existence d’une personne. Si vous voulez remonter le temps, suivez le guide ! Commencez par utiliser Facebook en anglais (US). Ensuite, allez à la page des paramètres du compte. Puis cliquer sur « Learn More » à La suite >

About the proprietary D compiler DMD

Jonathan Mercier

Dear reader,

Since fedora 14 they are a free and open source compiler LDC. D programmer can use too Digital Mars D compiler DMD. In D world they are 2 D version D1 and D2. DMD compiler can compile only in 32 bits, but this the compiler the most used.

DMD version 1

Install DMD v1

you need install DMD v1 form this package:

$ wget http://ftp.digitalmars.com/dmd-1.065-0.i386.rpm
$ su -m -c 'yum localinstall --nogpgcheck dmd-1.065-0.i386.rpm'

Modify dmd.conf

with DMD v1 you can use Tango as standard runtime library, for this you need edit /etc/dmd.conf file as:

[Environment]

DFLAGS= -I/usr/include/d/tango -I/usr/include/d -I/usr/include/d/tango/core/vendor -L-L/usr/lib/libtango-dmd.a -version=Tango -defaultlib=tango-dmd -debuglib=tango-dmd

Install tango-dmd

Take package here:

$ wget http://bioinfornatics.fedorapeople.org/tango-dmd-devel-0.99.9-1.20101109svn5599.fc14.i686.rpm
$ su -m -c 'yum localinstall --nogpgcheck tango-dmd-devel-0.99.9-1.20101109svn5599.fc14.i686.rpm tango-devel'

DMD version 2

Install DMD v2

Take package here:

$ wget http://ftp.digitalmars.com/dmd-2.050-0.i386.rpm
$ su -m -c 'yum localinstall --nogpgcheck dmd-2.050-0.i386.rpm'

Modify dmd.conf

With D2 you can not use Tango for the moment (only in D1) so you need use Phobos, for this edit /etc/dmd.conf as

[Environment]

DFLAGS= -I/usr/include/d/dmd/druntime/import/ -I/usr/include/d/dmd/phobos -I/usr/include/d -L-L/usr/lib/ -version=Phobos

Note

LDC developper and Tango developper works for port to D2 any help has appreciated

Tango

repository: git clone git://supraverse.net/tango.git

irc channel(freenode): #d.tango

LDC

repository: hg clone http://bitbucket.org/prokhin_alexey/ldc2

irc channel(freenode): #ldc

Thanks for all

signed: Bioinfornatics as Jonathan MERCIER

RPM Oracle Instant Client 11.2

Remi Collet

Un petit guide pour construire les RPM de Oracle Instant Client.

L'installation de Oracle Instant Client est certainement la solution la plus simple de disposer d'un accès aux bases Oracle depuis un client Unix/Linux/Windows/MacOS. Oracle fourni directement quelques RPM (utilisables sous Fedora) pour certaines versions et uniquement pour certaines architectures. Pour les autres versions, seules les archives aux... Lire RPM Oracle Instant Client 11.2

Page générée le 18 nov 2014 à 05:07