IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Rhino : un seul moteur pour plusieurs evaluations


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 59
    Par défaut Rhino : un seul moteur pour plusieurs evaluations
    Bonjour,
    je suis sur un programme qui gère des plugins en javascript, grâce à rhino.
    Je cherche à savoir s'il est possible de n'avoir qu'un seul moteur de script pour évaluer plusieurs scripts.
    Pour expliquer mon cas, je reprends un exemple minimal ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    import java.util.ArrayList;
    import javax.script.Invocable;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    public class Scripting {
        private interface Plugin {
            void display();
        }
        public static void main(String[] args) throws Exception {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine;
            ArrayList<Plugin> plugins = new ArrayList<Plugin>();
            String[] functions = {"function display() {println('plugin 1');}", "function display() {println('plugin 2');}", "function display() {println('plugin 3');}"};
            for (String f : functions) {
                engine = manager.getEngineByName("JavaScript");
                engine.eval(f);
                Invocable inv = (Invocable) engine;
                plugins.add(inv.getInterface(Plugin.class));
            }
            for (Plugin p : plugins) {
                p.display();
            }
        }
    }
    On a donc ici une interface "Plugin" avec juste une méthode à implémenter, 3 fonctions capable de l'implémenter, affichant chacune un texte.
    Je boucle ensuite sur les fonctions, je fais un eval dessus, et je stock le Plugin dans un tableau. Pour terminer je boucle sur tous les plugins et j'appelle "display()".
    Ce code fonctionne bien, à l'affichage j'ai bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    plugin 1
    plugin 2
    plugin 3
    Ce qui me gène est que je créé un nouveau moteur de script pour chaque plugin. Je me dis que dans un gros projet, ca peut être lourd.

    J'ai donc essayé ceci, pour n'utiliser qu'un seul moteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            ArrayList<Plugin> plugins = new ArrayList<Plugin>();
            String[] functions = {"function display() {println('plugin 1');}", "function display() {println('plugin 2');}", "function display() {println('plugin 3');}"};
            for (String f : functions) {
                engine.eval(f);
                Invocable inv = (Invocable) engine;
                plugins.add(inv.getInterface(Plugin.class));
            }
            for (Plugin p : plugins) {
                p.display();
            }
    Ici je ne créé qu'un seul moteur, puis ensuite dans ma boucle j'evalue le script et stock le plugin. A l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    plugin 3
    plugin 3
    plugin 3
    Chaque plugin se retrouve avec la dernière fonction évaluée. Ma question est donc :
    Est il possible avec Rhino de gérer plusieurs scripts, mais avec un seul moteur ?

    PS : j'ai vu qu'on peut faire des choses avec des "scope" et des "context", mais il semble que cela permet de gérer des valeurs différentes pour une même variable exportée dans un script, et non pas gérer plusieurs scripts pour un même moteur.

    Merci d'avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par eponyme Voir le message
    Est il possible avec Rhino de gérer plusieurs scripts, mais avec un seul moteur ?
    Oui tu peux... mais il faut faire avec le langage JavaScript...

    En JavaScript si tu définis 3 fois la même fonction, c'est la dernière qui sera prise en compte par le moteur.

    Dans ton cas comme tu n'as qu'un moteur tu remplaces à chaque fois la fonction par la dernière...


    Il serait plus judicieux de passer par des instances d'objets, par exemple en passant par la syntaxe JSON :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    obj = {
    	display : function() {
    		println('plugin 1');
    	}
    }
    Ici tu crée un objet avec une fonction.
    Si tu crée plusieurs objets tu auras bien plusieurs objets avec chacun sa(ses) fonction(s).


    Du coup tu peux t'en sortir en adaptant un peu ton code, afin de récupérer les instances après le eval() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
            ArrayList<Plugin> plugins = new ArrayList<Plugin>();
            String[] functions = {
            		"obj = { display: function() { println('plugin 1'); } }",
            		"obj = { display: function() { println('plugin 2'); } }",
            		"obj = { display: function() { println('plugin 3'); } }",
            };
     
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            Invocable invocable = (Invocable) engine;
            for (String f : functions) {
            	engine.setBindings(engine.createBindings(), ScriptContext.GLOBAL_SCOPE);
                Object result = engine.eval(f);
                if (result!=null) {
                	plugins.add(invocable.getInterface(result, Plugin.class));
                }
            }
            for (Plugin p : plugins) {
                p.display();
            }


    Maintenant je ne suis pas sûr que ce soit une bonne idée, puisque tu as quand même des risques de conflit si les plugins définissent des fonctions ou des variables globales.

    Le fait d'utiliser un moteur par plugins te permettrait de bien séparer chaque plugin...


    a++

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 59
    Par défaut
    Merci pour ton aide. Effectivement ca fonctionne bien.

    Du coup je suis un peu hésitant. Je pensais que ma façon de faire n'était pas "propre", et que je m'y prenais mal. Finalement ca semble avoir ses avantages.

    Si une application doit gérer de cette facon une trentaine de plugins, est ce que c'est "lourd" d'avoir un moteur pour chaque ? En fait je me fais une idée du moteur comme un truc un peu lourd, alors que peut etre pas du tout.

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Je n'ai strictement aucune idée des ressources mises en place par le moteur JS...

    Essaye de tester cela en jetant un coup d'oeil sur la mémoire avec jconsole...

    a++

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 59
    Par défaut
    Effectivement, je ferai des essais. En tout cas pour un grand nombre de plugins, je trouve plus sécurisant d'avoir un moteur par plugin, car comme tu l'as dis, cela permet de bien séparer, et d'etre sur qu'une variable globale d'un plugin ne vienne pas en écraser une autre.

    Merci pour ton aide.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 59
    Par défaut
    Bon et bien j'ai fait un petit essai, avec un chargement de 5 plugins. Une fois avec 5 moteurs, une fois avec 1 seul. Avec jconsole, je n'ai pas remarqué de grosse différence, le "heap" memory était a peu pres équivalent.

    Mais en y pensant, je me dis que de toute facon je ne conserve qu'un tableau de "Plugin". Si j'effectue le chargement dans une fonction séparée, en utilisant un moteur par plugin, ils seront de toute façon détruits à la fin de la fonction non ? Dans ce cas s'il devait y avoir une montée en charge, elle ne serait qu'au chargement des plugins, ce qui n'est pas tres grave.

    eponyme

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/07/2007, 13h45
  2. Est-ce possible d'utiliser un seul bd pour plusieurs site?
    Par Rajhonson dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 21/11/2006, 07h40
  3. un seul résultat pour plusieurs requètes
    Par MmoulinexX dans le forum Requêtes
    Réponses: 3
    Dernier message: 04/11/2006, 15h38
  4. Réponses: 7
    Dernier message: 01/02/2006, 15h49
  5. [C#] Une seule méthode pour plusieurs composants
    Par niPrM dans le forum Windows Forms
    Réponses: 8
    Dernier message: 01/06/2004, 14h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo