Pergunta

Eu uso o Eclipse IDE para desenvolver, compilar e executar meus projetos Java. Hoje, eu estou tentando usar a classe java.io.Console gerenciar a saída e, mais importante, a entrada do usuário.

O problema é que System.console() retornos null quando um aplicativo é executado "através de" Eclipse. Eclipse executar o programa em um processo de fundo, em vez de um processo de nível superior com a janela do console estamos familiarizados.

Existe uma maneira de forçar o Eclipse para executar o programa como um processo de nível superior, ou pelo menos criar uma consola que a JVM vai reconhecer? Caso contrário, eu sou forçado a jar o projeto e executar em um ambiente de linha de comando externo para Eclipse.

Foi útil?

Solução

Eu suponho que você quer ser capaz de usar passo através de depuração do Eclipse. Você pode apenas executar as classes externamente, definindo as classes construídas nos diretórios bin no classpath JRE.

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

Você pode depurar usando o depurador remoto e aproveitando os arquivos de classe construído em seu projeto.

Neste exemplo, a estrutura do projeto Eclipse esta aparência:

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

1. Inicie o Console de JVM no modo de depuração

debug.bat é um arquivo de lote do Windows que deve ser executado externamente a partir de um cmd.exe | console.

@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

Nos argumentos, a porta de depuração foi definido como 8787 . O suspender = y argumento conta a JVM esperar até que os adidos do depurador.

2. Criar uma configuração de ativação de depuração

No Eclipse, abra o diálogo Debug (Run> Debug Abrir diálogo ...) e criar um novo Remoto Java Application de configuração com as seguintes configurações:

  • Project: o nome do projeto
  • de Tipo de conexão: Padrão (soquete Anexar)
  • Anfitrião: localhost
  • Porto: 8787

3. Depuração ?

Então, tudo que você tem a fazer qualquer momento que você deseja depurar o aplicativo é:

  • definir um ponto de ruptura
  • lançar o arquivo de lote em um console
  • lançar a depuração de configuração

Você pode acompanhar esta questão em bug 122429 . Você pode trabalhar redonda esse problema no seu aplicativo usando uma camada de abstração como descrito aqui .

Outras dicas

A solução que eu uso é usar apenas System.in/System.out vez de Console ao utilizar Eclipse. Por exemplo, em vez de:

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

Você pode usar:

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

A razão isso ocorre é porque eclipse executa o seu aplicativo como um processo de fundo e não como um processo de nível superior com uma consola de sistema.

Você pode implementar uma classe de si mesmo. A seguir é um exemplo:

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

Encontrado algo sobre isso em http://www.stupidjavatricks.com/?p=43 .

E, infelizmente, já console é final, você não pode estendê-lo para criar um um invólucro em torno system.in e system.out que faz isso também. Mesmo dentro do console eclipse você ainda tem acesso a esses. Isso é provavelmente porque eclipse não ligado isso em seu console ainda ...

Eu entendo porque você não gostaria de ter qualquer outra forma de obter um console diferente System.Console, sem setter, mas eu não entendo por que você não iria querer que alguém seja capaz de substituir a classe para fazer um mock / console testando ...

Outra opção é criar um método para encerrar ambas as opções, e "fail over" para o método System.in quando Console não está disponível. O exemplo abaixo é um bastante básico - você pode seguir o mesmo processo para embrulhar os outros métodos em Console (readpassword, formato), conforme necessário. Dessa forma, você pode executá-lo feliz em Eclipse e quando a sua implantado você começa o Console apresenta (por exemplo esconder senha) chutando.

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

Tanto quanto eu posso dizer, não há nenhuma maneira para obter um objeto Console do Eclipse. Eu tinha acabado de se certificar de que consola! = Null, em seguida, JAR-lo e executá-lo a partir da linha de comando.

Não parece haver nenhuma maneira de obter um objeto java.io.Console ao executar um aplicativo através do Eclipse. Uma janela de console de linha de comando não é aberto com a aplicação, como ele é executado como um processo de fundo (fundo de Eclipse?). Atualmente, não há nenhuma Eclipse plug-in para lidar com esta questão, principalmente devido ao fato de que java.io.Console é uma classe final.

Tudo o que você realmente pode fazer é testar o objeto Console voltou para nula e proceder a partir daí.

Este ligação oferece alternativas ao uso de System.Console (). Uma é a utilização de um BufferedReader envolvida em torno System.in, a segunda é a utilização de um scanner envolvida em torno System.in.

Nem são tão conciso como console, mas ambos trabalham no eclipse, sem ter que recorrer a tolice debug!

Digamos que o seu espaço de trabalho Eclipse é C: \ MyWorkspace, você criou o aplicativo java dentro de um MyProject projeto Maven, e seu principal classe Java é com.mydomain.mypackage.MyClass.

Neste caso, você pode executar a classe principal que usos System.console() na linha de comando:

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

NB1: se não é em um projeto Maven, verifique a pasta de saída nas propriedades do projeto | Java Build Path | Fonte. Pode não ser "alvo / classes"

NB2: se é um projeto Maven, mas sua classe é em src / test / java, é provável que você tem que usar "alvo \ test-classes" em vez de "alvo \ classes"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top