web-dev-qa-db-fra.com

prise en charge de java.io.Console dans Eclipse IDE

J'utilise Eclipse IDE pour développer, compiler et exécuter mes projets Java. Aujourd'hui, j'essaie d'utiliser la classe Java.io.Console pour gérer les sorties et, plus important encore, les entrées de l'utilisateur.

Le problème est que System.console() renvoie null quand une application est exécutée "via" Eclipse. Eclipse exécute le programme sur un processus en arrière-plan plutôt que sur un processus de niveau supérieur avec la fenêtre de console avec laquelle nous sommes familiers.

Existe-t-il un moyen de forcer Eclipse à exécuter le programme en tant que processus de niveau supérieur ou au moins à créer une console que la machine virtuelle Java reconnaîtra? Sinon, je suis obligé de lancer le projet dans un fichier jar et de l'exécuter sur un environnement de ligne de commande externe à Eclipse.

102
Ross

Je suppose que vous voulez pouvoir utiliser le débogage étape par étape d’Eclipse. Vous pouvez simplement exécuter les classes en externe en définissant les classes construites dans les répertoires bin du chemin de classe JRE.

Java -cp workspace\p1\bin;workspace\p2\bin foo.Main

Vous pouvez déboguer à l'aide du débogueur distant et tirer parti des fichiers de classe intégrés à votre projet.

Dans cet exemple, la structure du projet Eclipse ressemble à ceci:

workspace\project\
                 \.classpath
                 \.project
                 \debug.bat
                 \bin\Main.class
                 \src\Main.Java

1. Démarrer la console JVM en mode débogage

debug.bat est un fichier de commandes Windows qui doit être exécuté en externe à partir d'une console cmd.exe.

@ECHO OFF
SET A_PORT=8787
SET A_DBG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=%A_PORT%,server=y,suspend=y
Java.exe %A_DBG% -cp .\bin Main

Dans les arguments, le port de débogage a été défini sur 8787. L'argument suspend = y indique à la JVM d'attendre que le débogueur se connecte.

2. Créer une configuration de lancement de débogage

Dans Eclipse, ouvrez la boîte de dialogue Débogage (Exécuter> Ouvrir une boîte de dialogue Débogage ...) et créez une nouvelle configuration Application Java distante avec les paramètres suivants:

  • Projet: le nom de votre projet
  • Type de connexion: Standard (Socket Attach)
  • Host: localhost
  • Port: 8787

3. Débogage

Donc, tout ce que vous avez à faire à tout moment pour déboguer l'application est:

  • définir un point de rupture
  • lancer le fichier batch dans une console
  • lancer la configuration de débogage

Vous pouvez suivre ce problème dans bug 122429 . Vous pouvez contourner ce problème dans votre application en utilisant une couche d'abstraction comme décrit ici .

50
McDowell

La solution de contournement que j'utilise consiste à utiliser uniquement System.in/System.out au lieu de la console lors de l'utilisation d'Eclipse. Par exemple, au lieu de:

String line = System.console().readLine();

Vous pouvez utiliser:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
35
Laplie Anderson

Cela s’explique par le fait qu’Eclipse exécute votre application en tant que processus en arrière-plan et non en tant que processus de niveau supérieur avec une console système. 

5
Heath Borders

Vous pouvez implémenter une classe vous-même. Voici un exemple:

public class Console {
    BufferedReader br;
    PrintStream ps;

    public Console(){
        br = new BufferedReader(new InputStreamReader(System.in));
        ps = System.out;
    }

    public String readLine(String out){
        ps.format(out);
        try{
            return br.readLine();
        }catch(IOException e)
        {
            return null;
        }
    }
    public PrintStream format(String format, Object...objects){
        return ps.format(format, objects);
    }
}
5
yztaoj

J'ai trouvé quelque chose à ce sujet sur http://www.stupidjavatricks.com/?p=43 .

Et malheureusement, puisque la console est finale, vous ne pouvez pas l’étendre pour créer un wrapper autour de system.in et system.out qui le fait non plus. Même dans la console Eclipse, vous avez toujours accès à ceux-ci. C'est probablement pourquoi Eclipse ne l'a pas encore insérée dans leur console ...

Je comprends pourquoi vous ne voudriez pas avoir d’autre moyen d’obtenir une console autre que System.console, sans setter, mais je ne comprends pas pourquoi vous ne voudriez pas que quelqu'un puisse remplacer la classe pour créer un maquette/test de la console ... 

4
John Gardner

Une autre option consiste à créer une méthode pour encapsuler les deux options et à "basculer" sur la méthode System.in lorsque la console n'est pas disponible. L'exemple ci-dessous est assez basique: vous pouvez suivre le même processus pour résumer les autres méthodes de la console (readPassword, format) selon vos besoins. De cette façon, vous pouvez l’utiliser avec plaisir dans Eclipse et, une fois déployé, vous obtiendrez les fonctionnalités de la console (masquage de mot de passe, par exemple).

    private static String readLine(String Prompt) {
        String line = null;
        Console c = System.console();
        if (c != null) {
             line = c.readLine(Prompt);
        } else {
            System.out.print(Prompt);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            try {
                 line = bufferedReader.readLine();
            } catch (IOException e) { 
                //Ignore    
            }
        }
        return line;
    }
4
binarycube

Autant que je sache, il n’ya aucun moyen d’obtenir un objet Console auprès d’Eclipse. Je voudrais juste m'assurer que la console! = Null, puis le JAR et l'exécuter à partir de la ligne de commande.

2
perimosocordiae

Il semble n'y avoir aucun moyen d'obtenir un objet Java.io.Console lors de l'exécution d'une application via Eclipse. Une fenêtre de la console de ligne de commande n'est pas ouverte avec l'application, car elle est exécutée en tant que processus en arrière-plan (l'arrière-plan d'Eclipse?). Actuellement, il n'y a pas de plugin Eclipse pour gérer ce problème, principalement parce que Java.io.Console est une classe finale.

Tout ce que vous pouvez réellement faire est de tester la valeur null de l'objet Console renvoyé et de continuer à partir de là.

1
Ross

This link offre une alternative à System.console (). La première consiste à utiliser un BufferedReader enroulé autour de System.in, la seconde consiste à utiliser un scanneur enveloppant System.in. 

Ni sont aussi concis que la console, mais les deux travaillent dans Eclipse sans avoir à recourir à déboguer la bêtise!

1
DaveRlz

Supposons que votre espace de travail Eclipse soit C:\MyWorkspace, Vous avez créé votre application Java dans un projet maven MyProject, Et que votre classe principale Java est com.mydomain.mypackage.MyClass.

Dans ce cas, vous pouvez exécuter votre classe principale qui utilise System.console() sur la ligne de commande:

Java -cp C:\MyWorkspace\MyProject\target\classes com.mydomain.mypackage.MyClass

NB1: si ce n'est pas dans un projet maven, vérifiez le dossier de sortie dans les propriétés du projet | Chemin de construction Java | La source. Ce n'est peut-être pas "cible/classes"

NB2: s'il s'agit d'un projet maven, mais que votre classe est en src/test/Java, vous devrez probablement utiliser "cible\classes de test" au lieu de "cible\classes"

0
Paulo Merson