Frage

Ich verwende die Eclipse-IDE zu entwickeln, kompilieren und meine Java-Projekte laufen. Heute Ich versuche, die java.io.Console Klasse zu verwenden, um Ausgaben und zu verwalten, was noch wichtiger ist, eine Benutzereingabe.

Das Problem ist, dass System.console() kehrt null, wenn eine Anwendung ausgeführt wird, „bis“ Eklipse. Die Eclipse starten Sie das Programm auf einem Hintergrundprozess, sondern als ein Top-Level-Prozess mit dem Konsolenfenster, wir sind vertraut mit.

Gibt es eine Möglichkeit von Eclipse zu zwingen, das Programm als Top-Level-Prozess ausgeführt werden, oder zumindest eine Konsole erstellen, die die JVM erkennen? Ansonsten bin ich gezwungen, das Projekt bis Glas und auf einer Befehlszeilenumgebung externe Eclipse ausgeführt werden.

War es hilfreich?

Lösung

Ich nehme an, Sie Schritt-through in der Lage sein wollen, von Eclipse-Debugging zu verwenden. Sie können nur die Klassen laufen extern durch die integrierten Klassen in den bin-Verzeichnissen auf dem JRE Classpath setzen.

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

Sie können Debuggen der Remote-Debugger und die Nutzung der Klassendateien in Ihrem Projekt gebaut werden.

In diesem Beispiel wird die Eclipse-Projektstruktur sieht folgendermaßen aus:

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

1. Starten Sie die JVM-Konsole im Debug-Modus

debug.bat ist eine Windows-Batch-Datei, die von einer cmd.exe Konsole extern ausgeführt werden soll.

@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

In den Argumenten hat die Debug-Port auf gesetzt wurde 8787 . Die suspendieren = y Argument erzählt die JVM zu warten, bis der Debugger legt.

2. Erstellen Sie eine Debug-Startkonfiguration

In Eclipse öffnen Sie das Debug-Dialog (Run> Öffnen Debug Dialog ...) und erstellen Sie eine neue Remote Java Application Konfiguration mit den folgenden Einstellungen:

  • Projekt: Ihr Projektname
  • Verbindungstyp: Standard (Sockel Attach)
  • Host: localhost
  • Port: 8787

3. Debuggen

Also, alles, was Sie jedes Mal, wenn Sie die App debuggen wollen tun müssen, ist:

  • setzen Sie einen Haltepunkt
  • Starten Sie die Batch-Datei in einer Konsole
  • Starten Sie die Debug-Konfiguration

Sie können dieses Problem verfolgen in bug 122429 . Sie können durch die Verwendung einer Abstraktionsschicht in Ihrer Anwendung runden dieses Problem umgehen, wie hier .

Andere Tipps

Die Abhilfe, die ich benutze, ist nur System.in/System.out statt Console zu verwenden, wenn Eclipse. Zum Beispiel statt:

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

Sie können mit:

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

Der Grund, dies geschieht, weil Eclipse Ihre Anwendung als Hintergrundprozess läuft und nicht als Top-Level-Prozess mit einer Systemkonsole.

können Sie eine Klasse selbst implementieren. Es folgt ein Beispiel:

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);
    }
}

Haben Sie etwas über diese unter http://www.stupidjavatricks.com/?p=43 .

Und leider, da Konsole endgültig ist, können Sie erweitern es keinen einen Wrapper um system.in und system.out zu schaffen, die es entweder tut. Selbst innerhalb der Eclipse-Konsole haben Sie noch Zugriff auf diese. Das ist wahrscheinlich, warum Eclipse diese in ihre Konsole nicht eingesteckt hat noch ...

Ich verstehe, warum Sie keine andere Möglichkeit haben wollen, ohne Setter eine Konsole andere als System.Console, zu bekommen, aber ich verstehe nicht, warum Sie nicht möchten, dass jemand die Klasse der Lage sein, außer Kraft zu setzen um eine Mock / Test Konsole ...

Eine andere Möglichkeit ist es, ein Verfahren zu schaffen, beide Optionen zu wickeln, und „Failover“ auf die System.in Methode, wenn Konsole nicht zur Verfügung. Das folgende Beispiel ist ein recht einfacher ein - Sie den gleichen Prozess folgen können, die anderen Methoden in Console (readPassword, Format) nach Bedarf einpacken. Auf diese Weise können sie glücklich in Eclipse laufen kann und wenn seine entfaltete Sie erhalten die Konsole Funktionen (zum Beispiel Passwort versteckt) treten in.

    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;
    }

Soweit ich das beurteilen kann, gibt es keine Möglichkeit, eine Konsole Objekt von Eclipse zu erhalten. Ich würde nur sicherstellen, dass Konsole! = Null, JAR es dann nach oben und es von der Kommandozeile ausgeführt werden.

Es scheint keine Möglichkeit zu geben ein java.io.Console Objekt zu erhalten, wenn eine Anwendung durch Eclipse-ausgeführt wird. Ein Befehlszeilen-Konsolenfenster ist nicht mit der Anwendung geöffnet, da es als einen Hintergrundprozess ausgeführt wird (Hintergrund Eclipse?). Derzeit gibt es keine Eclipse-Plugin um dieses Problem zu umgehen, vor allem aufgrund der Tatsache, dass java.io.Console eine letzte Klasse ist.

Alles, was Sie wirklich tun können ist testen Sie die zurück Console-Objekt für null und geht von dort aus.

Das Link bietet Alternativen zu System.Console () verwenden. Eine davon ist ein BufferedReader um System.in gewickelt zu verwenden, der zweite ist ein Scanner um System.in gewickelt zu verwenden.

Weder sind so präzise wie Konsole, aber beide Arbeit in Eclipse ohne zu debuggen silliness zu müssen!

Lassen Sie uns sagen, dass Ihre Eclipse-Workspace ist C: \ MyWorkspace, Sie erstellt Ihre Java-Anwendung in einem Maven-Projekt MyProject, und Java-Hauptklasse ist com.mydomain.mypackage.MyClass.

In diesem Fall können Sie Ihre Hauptklasse ausführen, die System.console() in der Befehlszeile verwendet:

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

NB1: wenn es nicht in einem Maven-Projekt ist, überprüfen Sie die Ausgabeordner in Projekteigenschaften | Java Build Pfad | Quelle. Es ist vielleicht nicht "target / classes"

sein

NB2: wenn es ein Maven-Projekt, aber die Klasse ist in src / test / java, Sie müssen wahrscheinlich "target \ test-Klassen" anstelle von "target \ classes" verwenden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top