Поддержка 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"