java.io. Поддержка консоли в Eclipse IDE

103

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

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

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

Росс
источник
Также см. Stackoverflow.com/questions/26470972/… Я определил System.outи System.inдостаточно для моего варианта использования и отказался от использования System.console().
OneWorld
Я экспортировал проект как runnable jar, но все еще получаю консольную ошибку null
Абигян

Ответы:

50

Я предполагаю, что вы хотите иметь возможность использовать пошаговую отладку из 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 . Приостановить = у аргумент сообщает JVM, чтобы ждать , пока отладчик атташе.

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

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

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

3. Отладка

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

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

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

Макдауэлл
источник
1
Я бы также поставил pauseв конец этого командного файла, чтобы вы могли видеть любые сообщения об ошибках, которые появляются перед его закрытием.
Мэтт Лайонс,
10
Это последняя капля для меня. Если мне нужно сделать все это только для отладки, я снова переключаюсь на Netbeans. В Eclipse так много нефиксированных ошибок и неудобств пользовательского интерфейса, что это даже не смешно.
нуццолило
@Nuzzolilo, это только для удаленной отладки. Вы можете отлаживать локально в eclipse без всего этого.
Лапли Андерсон
35

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

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

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

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
Лапли Андерсон
источник
20
Я не думаю, что таким образом вы сможете читать пароли с маскировкой пароля.
Суале Фатехи,
3
... и нужно обработать IOException, что не бросается в случае Console.readLine().
dma_k
5

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

Heath Borders
источник
5

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

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);
    }
}
Yztaoj
источник
4

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

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

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

Джон Гарднер
источник
4

Другой вариант - создать метод для обертывания обоих вариантов и «отработки отказа» для метода 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;
    }
двоичный куб
источник
2

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

перимосокордии
источник
1

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

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

Росс
источник
1

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

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

Дэйв Ричардсон
источник
0

Допустим, ваше рабочее пространство 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 | Источник. Это может быть не «цель / классы»

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

Пауло Мерсон
источник