Поддержка java.io.Console в Eclipse IDE

Я использую Eclipse IDE для разработки, компиляции и запуска моих проектов Java. Сегодня я пытаюсь использовать класс java.io.Console для управления выводом и, что более важно, ввода пользователем.

Проблема заключается в том, что System.console() возвращает null, когда приложение запускается "через" Eclipse. Eclipse запускает программу в фоновом режиме, а не в процессе верхнего уровня с помощью окна консоли, с которым мы знакомы.

Есть ли способ заставить Eclipse запускать программу как процесс верхнего уровня или, по крайней мере, создать консоль, которую JVM узнает? В противном случае я вынужден перестроить проект и запустить в среде командной строки, внешней по отношению к Eclipse.

Ответ 1

Я предполагаю, что вы хотите использовать сквозную отладку из Eclipse. Вы можете просто запустить классы извне, установив встроенные классы в каталоги bin в пути класса JRE.

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

Вы можете отлаживать использование удаленного отладчика и использовать файлы классов, созданные в вашем проекте.

В этом примере структура проекта Eclipse выглядит следующим образом:

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

1. Запустите консоль JVM в режиме отладки

debug.bat - командный файл Windows, который должен запускаться извне из консоли 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

В аргументах порт отладки был установлен в 8787. Параметр suspend = y указывает JVM ждать, пока отладчик не присоединяется.

2. Создание конфигурации запуска отладки

В Eclipse откройте диалоговое окно Отладка (Запустить > Открыть диалог отладки...) и создайте новую конфигурацию Удаленное Java-приложение со следующими настройками:

  • Проект: название проекта
  • Тип подключения: стандартный (гнездо для подключения)
  • Хост: localhost
  • Порт: 8787

3. Отладка

Итак, все, что вам нужно сделать, когда вы хотите отладить приложение, это:

  • установить точку останова
  • запуск командного файла в консоли
  • запустите конфигурацию отладки

Вы можете отслеживать эту проблему в ошибка 122429. Вы можете обойти эту проблему в своем приложении, используя слой абстракции, как описано здесь.

Ответ 2

Обходной путь, который я использую, - это просто использовать System.in/System.out вместо Console при использовании Eclipse. Например, вместо:

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

Вы можете использовать:

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

Ответ 3

Вы можете реализовать класс самостоятельно. Ниже приведен пример:

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

Ответ 4

Причина этого в том, что eclipse запускает ваше приложение как фоновый процесс, а не как процесс верхнего уровня с помощью системной консоли.

Ответ 5

Нашел что-то об этом в http://www.stupidjavatricks.com/?p=43.

И, к сожалению, поскольку консоль окончательна, вы не можете расширять ее, чтобы создать обертку вокруг system.in и system.out, которая тоже делает это. Даже внутри консоли eclipse у вас есть доступ к ним. Вероятно, почему Eclipse не подключил это в свою консоль еще...

Я понимаю, почему вы не хотели бы иметь другой способ получить консоль, отличную от System.console, без настройки, но я не понимаю, почему вы не хотите, чтобы кто-то мог переопределить класс создать тестовую консоль...

Ответ 6

Другим вариантом является создание метода для обертывания обоих параметров и "fail over" для метода System.in, когда консоль недоступна. Приведенный ниже пример довольно простой: вы можете выполнить один и тот же процесс, чтобы завершить другие методы в консоли (readPassword, format) по мере необходимости. Таким образом, вы можете успешно запустить его в Eclipse, и когда он будет развернут, вы сможете использовать функции консоли (например, скрытие пароля).

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

Ответ 7

Насколько я могу судить, нет способа получить объект консоли из Eclipse. Я бы просто удостоверился, что console!= Null, затем JAR и запустите его из командной строки.

Ответ 8

Кажется, нет способа получить объект java.io.Console при запуске приложения через Eclipse. Окно консоли командной строки не открывается приложением, поскольку оно выполняется как фоновый процесс (фон Eclipse?). В настоящее время для этой проблемы нет плагина Eclipse, в основном из-за того, что java.io.Console является окончательным классом.

Все, что вы действительно можете сделать, это проверить возвращаемый объект консоли для null и перейти оттуда.

Ответ 9

Эта ссылка предлагает альтернативы использованию System.console(). Один из них - использовать BufferedReader, обернутый вокруг System.in, второй - использовать сканер, обернутый вокруг System.in.

Ни то, ни другое не столь кратки, как консоль, но оба работают в eclipse, не прибегая к отладочной глупости!

Ответ 10

Скажем, ваше рабочее пространство Eclipse - это C:\MyWorkspace, вы создали свое приложение Java в проекте Maven MyProject, и ваш основной класс Java - com.mydomain.mypackage.MyClass.

В этом случае вы можете запустить основной класс, который использует System.console() в командной строке:

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

NB1: если он не в проекте maven, проверьте выходную папку в свойствах проекта | Путь сборки Java | Источник. Это может быть не "target/classes"

NB2: если это проект maven, но ваш класс находится в src/test/java, вам, скорее всего, придется использовать "target\test-classes" вместо "target\classes"