Domanda

Uso l'IDE Eclipse per sviluppare, compilare ed eseguire i miei progetti Java. Oggi sto cercando di utilizzare la classe java.io.Console per gestire l'output e, soprattutto, l'input dell'utente.

Il problema è che System.console () restituisce null quando viene eseguita un'applicazione da " a " Eclisse. Eclipse esegue il programma su un processo in background, piuttosto che su un processo di livello superiore con la finestra della console che conosciamo.

C'è un modo per forzare Eclipse a eseguire il programma come processo di livello superiore o almeno a creare una console che la JVM riconoscerà? Altrimenti, sono costretto a bloccare il progetto ed eseguirlo in un ambiente a riga di comando esterno a Eclipse.

È stato utile?

Soluzione

Presumo che tu voglia poter usare il debug passo-passo da Eclipse. Puoi semplicemente eseguire le classi esternamente impostando le classi integrate nelle directory bin sul percorso di classe JRE.

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

È possibile eseguire il debug utilizzando il debugger remoto e sfruttando i file di classe creati nel progetto.

In questo esempio, la struttura del progetto Eclipse è simile alla seguente:

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

1. Avvia la console JVM in modalità debug

debug.bat è un file batch di Windows che deve essere eseguito esternamente da una 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

Negli argomenti, la porta di debug è stata impostata su 8787 . L'argomento suspend = y dice alla JVM di attendere fino a quando il debugger si collega.

2. Crea una configurazione di avvio di debug

In Eclipse, apri la finestra di dialogo Debug (Esegui > Apri finestra di dialogo debug ...) e crea una nuova configurazione Applicazione Java remota con le seguenti impostazioni:

  • Progetto: il nome del tuo progetto
  • Tipo di connessione: Standard (Socket Attach)
  • Host: localhost
  • Porta: 8787

3. Debug

Quindi, tutto ciò che devi fare ogni volta che vuoi eseguire il debug dell'app è:

  • imposta un punto di interruzione
  • avvia il file batch in una console
  • avvia la configurazione di debug

Puoi tracciare questo problema in bug 122429 . Puoi aggirare questo problema nella tua applicazione usando un livello di astrazione come descritto qui .

Altri suggerimenti

La soluzione alternativa che utilizzo è utilizzare System.in/System.out anziché Console quando si utilizza Eclipse. Ad esempio, anziché:

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

Puoi usare:

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

Il motivo si verifica perché eclipse esegue l'app come processo in background e non come processo di livello superiore con una console di sistema.

Puoi implementare una classe tu stesso. Di seguito è riportato un esempio:

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

Trovato qualcosa a riguardo su http://www.stupidjavatricks.com/?p=43 .

E purtroppo, poiché la console è definitiva, non è possibile estenderla per creare un wrapper attorno a system.in e system.out che lo faccia neanche. Anche all'interno della console di Eclipse hai ancora accesso a quelli. Questo è probabilmente il motivo per cui eclipse non ha ancora inserito questo nella loro console ...

Capisco perché non vorresti avere un altro modo per ottenere una console diversa da System.console, senza setter, ma non capisco perché non vorresti che qualcuno fosse in grado di scavalcare la classe per creare una console di simulazione / test ...

Un'altra opzione è quella di creare un metodo per concludere entrambe le opzioni e "eseguire il failover". al metodo System.in quando la console non è disponibile. L'esempio che segue è abbastanza semplice: puoi seguire lo stesso processo per concludere gli altri metodi in Console (readPassword, formato) come richiesto. In questo modo puoi eseguirlo felicemente in Eclipse & amp; una volta distribuito, vengono visualizzate le funzionalità della console (ad es. nascondere la password).

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

Per quanto ne so, non c'è modo di ottenere un oggetto Console da Eclipse. Mi assicurerei solo che console! = Null, quindi esegua il JAR ed eseguirlo dalla riga di comando.

Sembra che non ci sia modo di ottenere un oggetto java.io.Console quando si esegue un'applicazione tramite Eclipse. Una finestra della console della riga di comando non viene aperta con l'applicazione, poiché viene eseguita come processo in background (da sfondo a Eclipse?). Attualmente, non esiste un plug-in Eclipse per gestire questo problema, principalmente a causa del fatto che java.io.Console è una classe finale.

Tutto quello che puoi fare è testare l'oggetto Console restituito per null e procedere da lì.

Questo link offre alternative all'utilizzo di System.console (). Uno è usare un BufferedReader avvolto intorno a System.in, il secondo è usare uno scanner avvolto intorno a System.in.

Nessuno dei due è conciso come la console, ma entrambi funzionano in eclissi senza dover ricorrere alla stupidità di debug!

Supponiamo che l'area di lavoro di Eclipse sia C: \ MyWorkspace, hai creato la tua applicazione java all'interno di un progetto maven MyProject, e la tua classe principale Java è com.mydomain.mypackage.MyClass.

In questo caso, puoi eseguire la tua classe principale che utilizza System.console () dalla riga di comando:

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

NB1: se non si trova in un progetto maven, controllare la cartella di output nelle proprietà del progetto | Percorso di costruzione Java | Fonte. Potrebbe non essere " target / classi "

NB2: se si tratta di un progetto maven, ma la tua classe è in src / test / java, probabilmente dovrai usare " target \ test-classi " invece di " target \ classes "

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top