Réalisation d'un script.bat à partir d'un programme en java sous eclipse

Résolu
Bonjour,

J'ai créé sur eclipse un programme qui résout un sudoku.

import java.io.IOException;
import java.nio.file.*;
import java.util.Arrays;

public class Sudoku {
    private static final int TAILLE = 9;
    private static final String PREFIX = "#";
    private static final int VIDE = 0;
    
    
    private final int[][] values;
    public Sudoku(int[][] tableau) {
  this.values = new int[TAILLE][TAILLE];
  for (int i = 0; i < TAILLE; i++) {
   for (int j = 0; j < TAILLE; j++) {
    this.values[i][j] = tableau[i][j];
   
    }
 }
    }
    
    // Lecture du fichier .txt 
    public Sudoku(Path filePath) throws IOException {
        values = Files.lines(filePath).map(String::trim).filter(Sudoku::isLineCorrect).map(Sudoku::readLine).toArray(int[][]::new);
        if (values.length != TAILLE)
            throw new IllegalArgumentException(values.length + " lines found, " + TAILLE + " expected " + this);
    }

    private static boolean isLineCorrect(final String trimLine) {
        return trimLine.length() == TAILLE && !trimLine.startsWith(PREFIX);
    }

    private static int[] readLine(final String trimLine) {
        return trimLine.chars().map(Sudoku::readValue).toArray();
    }

    private static int readValue(int character) {
        return (character >= '1' && character <= '9') ? (character - '0') : VIDE;
    }

    
    public String toString() {
        return Arrays.deepToString(values);
    }
    

 // Nombre de possibilité dans une rangée
  private boolean ligne(int r, int n) {
   for (int i = 0; i < TAILLE; i++)
    if (values[r][i] == n)
     return true;

   return false;
  }

  // Nombre de possibilité dans une colonne
  private boolean colonne(int c, int n) {
   for (int i = 0; i < TAILLE; i++)
    if (values[i][c] == n)
     return true;

   return false;
  }

  // Nombre de possibilité dans une sous-grille
  private boolean sousGrille(int r, int c, int n) {
   int ligne = r - r % 3;
   int colonne = c - c % 3;

   for (int i = ligne; i < ligne + 3; i++)
    for (int j = colonne; j < colonne + 3; j++)
     if (values[i][j] == n)
      return true;

   return false;
  }

  // On vérifie que le nombre est présent sur une ligne et une colonne et dans une
  // sous-grille
  private boolean x(int r, int c, int n) {
   return !ligne(r, n) && !colonne(c, n) && !sousGrille(r, c, n);
  }
    
 // Méthode de résolution

  public boolean solver() {
   for (int ligne = 0; ligne < TAILLE; ligne++) {
    for (int colonne = 0; colonne < TAILLE; colonne++) {
     
     
     if (values[ligne][colonne] == VIDE) {
      
      for (int n = 1; n <= TAILLE; n++) {
       if (x(ligne, colonne, n)) {
        
        values[ligne][colonne] = n;

        if (solver()) { 
         return true;
        } else { 
         values[ligne][colonne] = VIDE;
        }
       }
      }

      return false; 
     }
    }
   }

   return true; 
  }

  // Affichage
  public void affichage() {
   for (int i = 0; i < TAILLE; i++) {
    for (int j = 0; j < TAILLE; j++) {
     System.out.print(" " + values[i][j]);
    } 
     
    System.out.println();
   }
   System.out.println();
  
  }

    
    public static void main(String[] args) throws IOException {
        
        Sudoku monSudoku = new Sudoku(Paths.get("fichier/monSudoku grille1.txt"));
  System.out.println("Grille à résoudre");
  monSudoku.affichage();
  
  // Essai de la résolution du sudoku
  if (monSudoku.solver()) {
   System.out.println("Solution du Sudoku");
   monSudoku.affichage();
  } else {
   System.out.println("Pas de solution pour cette grille");
    }
 }
}

Le programme fonctionne très bien.
Toutefois, je dois l'exécuter avec un fichier.bat et je dois l'invoquer par la commande suivante : java -cp . monSudoku grille1.txt

J'ai donc essayé ceci :

LanceSudoku.bat
REM ---- Defenir l'environnement de compil
set path="C:\Program Files\Java\jdk-14\bin"

REM ---- Compiler les sources

javac Sudoku.java

REM ---- Executer les programmes

java -cp . monSudoku grille1.txt
java -cp . Sudoku

Mais rien ne fonctionne

Comment fait-on pour récupérer un fichier à partir du programme sous eclipse pour pouvoir l'exécuter dans un fichier .bat avec la commande ci-dessus ?

Toute aide sera la bienvenue

10 réponses

  1. Modérateur
    Bonjour,

    Essayes avec ceci dans ton fichier .bat :

    "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
    "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku grille1.txt
    pause

    1. Bonsoir,

      J'ai essayé ce que tu m'as proposé, et ça n'a rien changé
      1. Modérateur
        Et quels sont les messages affichés ?
        Soit la compilation échoue, soit l'exécution, mais si tu ne nous donnes pas les messages d'erreurs on ne peut pas t'aider à les résoudre...
    2. mon premier script affiche le message suivant :

      LanceSudoku.bat
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Defenir l'environnement de compil

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>set path="C:\Program Files\Java\jdk-14\bin"

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Compiler les sources

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>javac Sudoku.java

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Executer les programmes

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>java -cp . monSudoku grille1.txt
      Error: Could not find or load main class monSudoku
      Caused by: java.lang.ClassNotFoundException: monSudoku

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>java -cp . Sudoku
      Exception in thread "main" java.nio.file.NoSuchFileException: fichier\monSudoku grille1.txt
      at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
      at java.base/sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:120)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:292)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:345)
      at java.base/java.nio.file.Files.lines(Files.java:4102)
      at java.base/java.nio.file.Files.lines(Files.java:4194)
      at Sudoku.<init>(Sudoku.java:24)
      at Sudoku.main(Sudoku.java:130)

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...

      Et avec ce que tu m'as donné plus haut, ça donne ceci :

      LanceSukoku.bat
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Defenir l'environnement de compil

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>set path="C:\Program Files\Java\jdk-14\bin"

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Compiler les sources

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>javac Sudoku.java

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Executer les programmes

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>java -cp . monSudoku grille1.txt
      Error: Could not find or load main class monSudoku
      Caused by: java.lang.ClassNotFoundException: monSudoku

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>java -cp . Sudoku
      Exception in thread "main" java.nio.file.NoSuchFileException: fichier\monSudoku grille1.txt
      at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
      at java.base/sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:120)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:292)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:345)
      at java.base/java.nio.file.Files.lines(Files.java:4102)
      at java.base/java.nio.file.Files.lines(Files.java:4194)
      at Sudoku.<init>(Sudoku.java:24)
      at Sudoku.main(Sudoku.java:130)

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku grille1.txt
      Exception in thread "main" java.nio.file.NoSuchFileException: fichier\monSudoku grille1.txt
      at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
      at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
      at java.base/sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:120)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:292)
      at java.base/java.nio.channels.FileChannel.open(FileChannel.java:345)
      at java.base/java.nio.file.Files.lines(Files.java:4102)
      at java.base/java.nio.file.Files.lines(Files.java:4194)
      at Sudoku.<init>(Sudoku.java:24)
      at Sudoku.main(Sudoku.java:130)

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...

      J'ai constaté qu'il y avait un souci avec la méthode main, mais même en l'a modifiant, ça ne change rien, du coup je ne sais pas comment résoudre ce problème
      1. Modérateur
        Ce que je t'ai donné suffisait pour le .bat tout le reste que tu as mis avant ne sert à rien.

        Le problème vient du code, tu n'utilises pas le paramètre du programme, car tu as écrit le chemin du fichier en dur dans le code...

        Il faut modifier
        Paths.get("fichier/monSudoku grille1.txt"))
        par
        Paths.get(args[0])
        .
    3. Même après avoir modifié le fichier.bat et le programme comme indiqué précédemment, j'ai toujours un problème avec la méthode main

      LanceSudoku.bat

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\java.exe" monSudoku grille1.txt
      Error: Could not find or load main class monSudoku
      Caused by: java.lang.ClassNotFoundException: monSudoku

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...

      De plus, dans le fichier.bat, je dois invoquer l'exécution par la commande suivante : java -cp . monSudoku grille1.txt (consigne demandée)
      C'est pour ça que j'avais gardé cela dans mon fichier.bat
      1. Modérateur
        -cp .
        ne sert à rien, c'est la valeur par défaut, donc avec ou sans ça doit faire la même chose.

        Le problème c'est que "monSudoku" ça n'existe pas.
        Le nom de ta classe c'est "Sudoku", tu compiles le fichier Sudoku.java, ça génère un fichier Sudoku.class, tu dois donc exécuter
        java Sudoku
    4. Donc si je dois exécuter
      java Sudoku
      , j'ai modifié mon fichier.bat comme suit :

      REM ---- Defenir l'environnement de compil
      set path="C:\Program Files\Java\jdk-14\bin"

      REM ---- Compiler les sources

      javac Sudoku.java

      REM ---- Executer les programmes

      java -cp . Sudoku
      pause

      et ça a donné ceci :

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Defenir l'environnement de compil

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>set path="C:\Program Files\Java\jdk-14\bin"

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Compiler les sources

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>javac Sudoku.java

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>REM ---- Executer les programmes

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>java -cp . Sudoku
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
      at Sudoku.main(Sudoku.java:130)

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...

      En fait, avec ce que tu me dis je ne comprends pas la deuxième ligne que tu m'as proposé

      "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku grille1.txt
      pause
      1. Modérateur
        "je ne comprends pas la deuxième ligne que tu m'as proposé"
        C'est une version corrigée de ce que tu avais mis dans le .bat de ta question :
        java -cp . monSudoku grille1.txt

        Avec
        -cp .
        en moins puisque ça ne sert à rien et Sudoku au lieu de monSudoku...

        Quant à ton erreur c'est parce que tu ne fais pas ce que je dis... Pour que args[0] fonctionne il faut passer le nom fichier en paramètre, c'est à dire
        Sudoku grille1.txt
        pas
        Sudoku
        tout seul, sinon le programme ne sait pas quel fichier ouvrir.

        https://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html
    5. D'accord je comprends mieux,

      alors j'ai modifié mon fichier.bat comme tu m'as dit :

      "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku grille1.txt
      pause


      et ça a donné le résultat suivant :

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku grille1.txt
      Exception in thread "main" java.nio.file.NoSuchFileException: grille1.txt
              at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
              at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
              at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
              at java.base/sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:120)
              at java.base/java.nio.channels.FileChannel.open(FileChannel.java:292)
              at java.base/java.nio.channels.FileChannel.open(FileChannel.java:345)
              at java.base/java.nio.file.Files.lines(Files.java:4102)
              at java.base/java.nio.file.Files.lines(Files.java:4194)
              at Sudoku.<init>(Sudoku.java:24)
              at Sudoku.main(Sudoku.java:130)
      
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...


      Ca ne fonctionne toujours pas...
      1. Modérateur
        Et il est où ton fichier grille1.txt ?
        Java va le chercher dans le classpath (le fameux
        -cp .
        ) c'est à dire dans le même dossier que Sudoku.class pour l'instant.
    6. Bonjour,

      Si tu ne lui donnes pas le chemin du fichier grille1.txt il ne risque pas de le trouver tout seul.

      Tu utilises mal la variable PATH, tu as dégagé tout le contenu de la variable pour ne laisser que java, c'est pas très malin.
      1. Bonjour,

        où dois renseigner le chemin du fichier grille1 ?

        J'ai utilisé la variable PATH pour que mon programme fonctionne sur eclipse.
        J'ai inséré mon fichier monSudoku grille1.txt directement dans un fichier de mon projet java pour qu'il fonctionne peu importe l'endroit où il se trouve.
      2. Modérateur
        Le chemin du fichier n'est pas obligatoire, il va être pris en relatif dans le classpath du programme (y compris si celui-ci est composé de plusieurs dossiers).

        Quant à la variable path, c'est juste une surcharge dans le contexte du batch, ce n'est pas grave vu qu'il n'y a rien besoin d'autres que le JDK.
    7. Qu'est ce que je dois alors faire pour que mon fichier "monSudoku grille 1.txt" soit lu avec le fichier lanceSudoku.bat ?

      Comme je l'ai dit, pour le moment mon fichier "monSudoku grille 1.txt" est dans un fichier dans mon projet java Sudoku (d'où ("fichier/monSudoku grille1.txt")). Ce n'est pas cela qu'il faut faire ?
      1. Il faut rajouter des doubles quotes autour de ton argument car celui-ci contient un ou plusieurs espaces :

        "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
        "C:\Program Files\Java\jdk-14\bin\java.exe" "Sudoku grille1.txt"
        pause
      2. Modérateur
        Ce n'était pas du tout dit que ton fichier s'appelait "monSudoku grille 1.txt" mais je comprends mieux d'où vient ce "monSudoku"...

        Du coup ta commande doit être :
        "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku "monSudoku grille 1.txt"

        À condition que le fichier "monSudoku grille 1.txt" soit dans le même dossier que Sudoku.class et lanceSudoku.bat
    8. J'ai modifié mon fichier "monSudoku grille1.txt" par Sudoku.txt, car ma classe principale se nomme Sudoku, mais ça ne fonctionne toujours pas

      @echo off
      
      
      set file="C:\Users\Magali\Documents\perso\NFP135-1\sudoku\Sudoku.txt"
      type %file%
      
      pause
      
      java -cp . Sudoku.txt
      "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku.txt
      pause


      J'ai le résultat suivant

      # -----------------------
      # Fichier grille1.txt
      # -- Exemple de fichier de definition d'une grille
      # -----------------------
      123456789
      .6.....3.
      .7.....4.
      789123456
      .........
      .........
      456789123
      .........
      .........
      #    -------------------------
      #    | 1 2 3 | 4 5 6 | 7 8 9 |
      #    | . 6 . | . . . | . 3 . |
      #    | . 7 . | . . . | . 4 . |
      #    -------------------------
      #    | 7 8 9 | 1 2 3 | 4 5 6 |
      #    | . . . | . . . | . . . |
      #    | . . . | . . . | . . . |
      #    -------------------------
      #    | 4 5 6 | 7 8 9 | 1 2 3 |
      #    | . . . | . . . | . . . |
      #    | . . . | . . . | . . . |
      #    ------------------------- Appuyez sur une touche pour continuer...
      Erreur : impossible de trouver ou charger la classe principale Sudoku.txt
      Error: Could not find or load main class Sudoku.txt
      Caused by: java.lang.ClassNotFoundException: Sudoku.txt
      Appuyez sur une touche pour continuer...


      Je ne sais vraiment plus quoi faire pour que le script affiche ma grille résolue...
      1. Modérateur
        Tu as oublié le nom de la classe ce qui est le plus important, java ne va pas ouvrir un fichier txt !

        java.exe Sudoku Sudoku.txt
    9. Ca y est, ça a fonctionné ! Je voulais vous remercier pour l'aide que vous m'avez apporté.

      Du coup, mon fichier LanceSudoku.bat donne ceci :

      "C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      "C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku "monSudoku grille1.txt"
      pause


      et j'obtiens bien le même résultat que sur eclipse

      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\javac.exe" Sudoku.java
      
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>"C:\Program Files\Java\jdk-14\bin\java.exe" Sudoku "monSudoku grille1.txt"
      Grille à résoudre
       1 2 3 4 5 6 7 8 9
       0 6 0 0 0 0 0 3 0
       0 7 0 0 0 0 0 4 0
       7 8 9 1 2 3 4 5 6
       0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0
       4 5 6 7 8 9 1 2 3
       0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0
      
      Solution du Sudoku
       1 2 3 4 5 6 7 8 9
       5 6 4 8 9 7 2 3 1
       9 7 8 2 3 1 6 4 5
       7 8 9 1 2 3 4 5 6
       2 3 1 5 6 4 8 9 7
       6 4 5 9 7 8 3 1 2
       4 5 6 7 8 9 1 2 3
       3 1 2 6 4 5 9 7 8
       8 9 7 3 1 2 5 6 4
      
      
      C:\Users\Magali\Documents\perso\NFP135-1\sudoku>pause
      Appuyez sur une touche pour continuer...


      J'ai juste une dernière question

      Dans mon projet java sur eclipse, pour que mon programme fonctionne avec mon fichier "monSudoku grille1.txt", je dois avoir la commande suivante dans la classe main :

          public static void main(String[] args) throws IOException {
              
              Sudoku monSudoku = new Sudoku(Paths.get("fichier/monSudoku grille1.txt"));
        System.out.println("Grille à résoudre");
        monSudoku.affichage();
        
        // Essai de la résolution du sudoku
        if (monSudoku.solver()) {
         System.out.println("Solution du Sudoku");
         monSudoku.affichage();
        } else {
         System.out.println("Pas de solution pour cette grille");
          }
       }


      Alors que pour faire fonctionner mon fichier LanceSudoku.bat, je dois modifier
      Sudoku monSudoku = new Sudoku(Paths.get("fichier/monSudoku grille1.txt"));

      par
      Sudoku monSudoku = new Sudoku(Paths.get(args[0]));
      1. Je ne connais rien à Java ni Eclipse (est-ce un IDE ?), mais je suppose que quand tu exécutes ton programme tu ne lui passes pas de paramètre donc tu es obligé d'indiquer le chemin en "dur".

        C'est quand même plus pratique et élégant de passer la grille en paramètre, plutôt que devoir modifier le fichier Java à chaque fois que tu veux traiter une autre grille, non ?

        Je peux t'aider pour le script .bat, qui devrait ressembler à ça :

        @echo off

        set PATH=%PATH%;C:\Program Files\Java\jdk-14\bin

        if exist "%~dpn1.txt" (

        type "%~1"
        javac.exe Sudoku.java
        java.exe Sudoku "%~1"

        )

        pause


        Ainsi tu auras juste à faire glisser la grille sur le batch pour que ça fonctionne, plus besoin de modifier le nom de la grille à chaque fois.
      2. Modérateur
        Dans Eclipse, tu vas dans "Run > Run Configurations". Tu devrais arriver directement dans "Java Application" sur un projet "Sudoku", éventuellement "Sudoku (1)", "Sudoku (2)"...
        Dans le premier onglet "Main" tu vas avoir "Sudoku" dans la catégorie Main Class.
        Ce qui t'intéresse c'est l'onglet "Arguments" où tu peux préciser dans "Program Arguments" la valeur "fichier/monSudoku grille1.txt" qui sera alors attribué à la valeur args[0] de la méthode main, comme en passant par le batch.
      3. @KXMerci beaucoup, ça a fonctionné
        C'est plus pratique en effet !