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

Java Discussion :

Faire un éditeur/compilateur simple


Sujet :

Java

  1. #1
    Membre actif
    Faire un éditeur/compilateur simple
    Bonjour,

    je travaille sur l'aspect développement de mon projet de jeu vidéo, AnAcondA. Suite à une discussion sur les possibilités d'hébergement, j'ai cherché à me rapprocher autant que possible des modalités Open Source.

    J'ai donc développé un outil permettant de programmer avec les librairies d'AnAcondA. Pour l'instant, cet outil génère un code simple permettant de faire facilement un player de mp3 ou une calculatrice personnalisables.

    Le code généré est très simple, dans le but de présenter les fonctionnalités accessibles d'AnAcondA et de faciliter la personnalisation.

    Suite à la génération du code, je propose un outil permettant de faire la compilation du projet choisi. La compilation est faite par la commande javac invoquée à travers un Runtime.getRuntimeà.exec("javac monprojet.java").

    La compilation fonctionne très bien mais je n'arrive pas à afficher les messages que javac produit afin d'indiquer à l'utilisateur si son projet est correct ou s'il y a des erreurs de compilation.

    Je voudrais savoir comment récupérer ces messages d'erreurs à la compilation pour les afficher afin que l'utilisateur puisse les corriger.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  2. #2
    Expert éminent sénior
    David Delbecq Java developer chez HMS Industrial Networks AB.    LinkedIn | Google+

  3. #3
    Membre actif
    exec et javac
    j'ai regardé les données sur la commande exec à partir du lien et cela correspond à la façon dont j'utilise exec.

    J'ai fait un méthode exec pour une utilisation qui renvoie les lignes tirées des flux "in" et "err". Mais ça ne renvoie pas les erreurs lancées par javac.

    La solution que j'utilise actuellement consiste à utiliser javac avec le paramètre -Xstdout et lire ensuite ce que javac écrit dans le fichier indiqué :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    exec("javac -O -Xstdout resultat.txt monFichier.java");

    Mais je voudrais récupérer les erreurs sans passer par le disque dur et je n'y arrive pas en lisant les flux sortis de exec.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  4. #4
    Invité
    Invité(e)
    Salut,

    Je ne sais pas si tu sais, mais il y a un meilleurs moyen d'appeler le (un) compilateur java depuis du code java depuis la version 6 : http://java.sun.com/javase/6/docs/ap...aCompiler.html
    ça devrait te permettre d'éviter une appel système explicit et rendre la chose plus portable. La classe Diagnostic peut aussi éventuellement te simplifier la récupération des erreurs.

  5. #5
    Expert éminent sénior
    Citation Envoyé par anadoncamille Voir le message

    J'ai fait un méthode exec pour une utilisation qui renvoie les lignes tirées des flux "in" et "err". Mais ça ne renvoie pas les erreurs lancées par javac.
    Tu peux montrer ce code?
    David Delbecq Java developer chez HMS Industrial Networks AB.    LinkedIn | Google+

  6. #6
    Membre actif
    java 1.4
    Bonjour,

    utilisant le bundle forte java1.4, je suis limité en versions java à la 1.4, donc les méthodes de compilation disponibles à la 1.6 ne me sont pas accessibles. Je les ai bien vues sur la doc que j'utilise mais n'ai pas pu les utiliser.

    Voici le code que j'utilise pour ma commande exec :
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
     
      public static Vector exec(String command) {
        System.out.println("8=) " + command); // affichage d'un prompt
        Vector resultLines = new Vector();
        Vector errorLines = new Vector();
        try {
          Process p = Runtime.getRuntime().exec(command);
          InputStream is = p.getInputStream();
          InputStream es = p.getErrorStream();
          BufferedReader br = new BufferedReader(new InputStreamReader(is));
          BufferedReader br2 = new BufferedReader(new InputStreamReader(es));
          String res = br.readLine();
          String res2 = br2.readLine();
          boolean read = (res != null) || (res2 != null);
          while (read) {
            read = false;
            res = br.readLine();
            res2 = br.readLine();
            if (res != null) {
              read = true;
              resultLines.add(res);
              System.out.println("OUT : " + res);
              FNEC.WRITE("OUT : " + res); // affichage sur la console graphique d'AnAcondA, equivalent à println
            }
            if (res2 != null) {
              read = true;
              errorLines.add(res2);
              System.out.println("ERR : " + res2);
              FNEC.WRITE("ERR : " + res2);
            }
            FNEC.respire(); // équivalent à Thread.yield, pour aérer le programme
          }
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        System.out.println("8=)\n");
        resultLines.addAll(errorLines);
        return resultLines;
      }


    Pour la commande compile que j'utilise actuellement, cela donne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      public static Vector compile(String file) {// file est un fichier.java ou un package
        String cFile = "compile.log";
        String command = "javac -Xstdout " + cFile + " -O " + file;
        if (file.indexOf(".") < 0)
          command += "/*.java";
        KOS.exec(command);
        if (!KOS.exists(cFile)) // equivalent à File.exists()
          return new Vector();
        Vector out = DirectTextIO.getText(cFile); // renvoie la liste des lignes d'un fichier texte
        KOS.deleteFile(cFile); // efface le fichier résultant de la compilation
        return out;
      }


    Pour build :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      public static Vector build(String dir) {// dir désigne la racine du dossier à compiler
        Vector out = new Vector();
        KOS.deleteFiles(dir, "class"); // clean, effacement des anciennes classes
        Vector vj = KOS.getFileList(dir, "java"); // liste des fichiers à compiler
        String b = "build.log";
        DirectTextIO.setText(b, vj); // écriture de la liste des fichiers à compiler
        out.addAll(compile("@" + b)); // transmission à la commande compile et récupération des messages
        KOS.deleteFile(b); // effacement de la liste de fichiers à compiler
        return out;
      }


    C'est du code qui fonctionne bien. Ce qui m'embête est d'avoir à passer par le disque dur pour retrouver les messages de compilation. L'impression que j'ai est que la version 1.6 de java est plus accessible, mais pour l'instant je suis limité à la 1.4 . Donc finalement je n'utilise pas le flux renvoyé par exec pour gérer l'affichage des messages de compilation mais j'utilise la fonction -Xstdout de javac, puis je lis le fichier des messages.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  7. #7

  8. #8
    Membre actif
    ProcessLauncher
    Salut,

    j'ai lu la classe ProcessLauncher, mais le fonctionnement est à priori identique à ce que j'ai codé. Je vais quand même l'essayer avec javac pour voir si j'arrive à récupérer le flux de sortie généré
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  9. #9
    Membre actif
    re:ProcessLauncher
    Bon, mon code de exec est erroné. Avec le code de ProcessLauncher, javac renvoie bien sa liste d'erreurs dans le flux err et on peut le récupérer en mémoire ou sur disque. J'ai fait les essais sur disque, ça donne ceci :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      public static void execJavac(String file) {
        try {
          OutputStream out = new FileOutputStream("testJavacOut.txt");
          OutputStream err = new FileOutputStream("testJavacErr.txt");
          ProcessLauncher pl = new ProcessLauncher(out, err);
          pl.exec("javac " + file);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }

    En testant sur un fichier volontairement erroné, j'ai bien obtenu la liste des erreurs à corriger dans le fichier testJavacErr.txt

    Une ligne à modifier dans ProcessLauncher, pour une gestion d'exception :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    private int execute() {

    à remplacer par
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    private int execute() throws IOException  {


    Sur ce, je m'en vais rectifier mon code. Merci pour votre aide.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

###raw>template_hook.ano_emploi###