System.console () повертає значення null


78

Я використовував readLineз , BufferedReaderщоб отримати введення / новий пароль від користувача, але хотів , щоб приховати пароль , так що я намагаюся використовувати java.io.Consoleклас. Проблема полягає в тому, що System.console()повертається nullпри налагодженні програми в Eclipse. Я новачок у Java та Eclipse. Не впевнений, що це найкращий спосіб досягти? Я натискаю правою кнопкою миші на вихідному файлі та вибираю "Налагодження як"> "Застосування Java". Чи є якийсь обхідний шлях?


1
Також див. Stackoverflow.com/questions/26470972/… Я визначив System.outі System.inдостатній для мого випадку використання та відмови від використання System.console().
OneWorld

Відповіді:



33

Цей фрагмент коду повинен зробити трюк:

private String readLine(String format, Object... args) throws IOException {
    if (System.console() != null) {
        return System.console().readLine(format, args);
    }
    System.out.print(String.format(format, args));
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));
    return reader.readLine();
}

private char[] readPassword(String format, Object... args)
        throws IOException {
    if (System.console() != null)
        return System.console().readPassword(format, args);
    return this.readLine(format, args).toCharArray();
}

Під час тестування в Eclipse введення пароля буде чітко показано. Принаймні, ви зможете протестувати. Тільки не вводьте справжній пароль під час тестування. Зберігайте це для виробничого використання;).


Чи повинен ваш ручний readLineметод закрити BufferedReaderблок нарешті (або спробувати з ресурсами)?
Andrew Swan,

Ні, тому що це закрило б відповідність System.in потік, і подальше читання після цього не могло бути здійснено.
formixian

Так, дивно, що цей потік можна закрити; Я очікував, що це буде ні.
Andrew Swan,

15

System.console() повертає null, якщо консолі немає.

Ви можете обійти це, додавши до вашого коду шар непрямої дії, або запустивши код на зовнішній консолі та приєднавши віддалений налагоджувач .


Це також повернуло для мене значення null у PowerShell при запуску чогось подібного java -cp ... Class | tee out.
lmat

9

Я також зіткнувся з цією проблемою, намагаючись написати просту програму командного рядка.

Ще однією альтернативою створенню власного об’єкта BufferedReader із System.in є використання java.util.Scanner таким чином:

import java.util.Scanner;

Scanner in;
in = new Scanner(System.in);

String s = in.nextLine();

Звичайно, це не буде простою заміною Console, але надасть вам доступ до різноманітних функцій введення.

Ось додаткова документація щодо сканера від Oracle .


7

Відповідно до документів :

Якщо віртуальна машина запускається автоматично, наприклад, за допомогою планувальника фонових завдань, тоді вона, як правило, не матиме консолі.


1
Ця відповідь привела мене до того, що якщо ви запускаєте Gradle з увімкненим deamon, ви не зможете отримати консоль у своїх завданнях Gradle. Запуск мого завдання Gradle за допомогою '--no-daemon' надає доступ до консолі.
whitespy9

Це трапилося зі мною при використанні крапельного ( github.com/ninjudd/drip ) для інструменту командного рядка. Ой!
Джордж Л

7

Відповідно до API :

" Якщо віртуальну машину запускати з інтерактивного командного рядка без перенаправлення стандартних потоків вводу та виводу, тоді її консоль буде існувати і, як правило, буде підключена до клавіатури та дисплея, з якого віртуальна машина була запущена. Якщо віртуальна машина запущена автоматично, наприклад фоновим планувальником завдань, тоді у нього зазвичай не буде консолі. "


4

Отримав це повідомлення про помилку під час запуску програми від Netbeans. Судячи з інших відповідей, схоже, це трапляється під час запуску вашої програми з IDE. Якщо ви поглянете на це запитання: спроба читати з консолі в Java , це тому, що

Більшість IDE використовують javaw.exe замість java.exe для запуску коду Java

Рішення полягає у використанні, command line/terminalщоб отримати Console.


1

Я вважаю, що в конфігураціях запуску для Eclipse ви можете налаштувати, призначати консоль чи ні - переконайтеся, що це позначено. (Минув деякий час з того часу, як я використовував Eclipse, тому я не можу дати конкретних вказівок, боюся).

Якщо це не спрацює, тоді щось, що обов’язково виконає цю роботу, - це запуск програми в режимі налагодження, а потім підключіться до процесу за допомогою Eclipse. Шукайте "віддалена налагодження eclipse", якщо ви не впевнені, як це зробити.

Більше того, загалом погано вимагати призначення консолі, оскільки це дуже впливає на гнучкість вашої програми - як ви щойно виявили. Багато способів виклику Java не призначають консоль, і ваша програма непридатна для використання в цих випадках (що погано). Можливо, ви можете дозволити вказувати аргументи в командному рядку. (Якщо ви спеціально тестуєте вхідні дані консолі, то досить справедливо, але потенційно людям було б корисно мати можливість викликати вашу програму зі сценаріїв та / або на безголових серверах, тому такий гнучкий дизайн майже завжди є гарною ідеєю . Це часто також призводить до більш упорядкованого коду.)


так, це лише для моєї налагоджувальної мети, користувачі отримають скрипт оболонки або файл bat. Хіба не приємно користуватися консоллю ?? якщо так, то який кращий спосіб
галлі

До речі, усі розмовні пошукові налагоджувальні розмови обговорюються на веб-сервері, але я не створюю веб-додаток. це звичайна Java. може бути кращим способом маскування пароля?
Галли

Ви можете віддалено налагоджувати будь-який процес Java, просто додайте, наприклад, -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000до аргументів віртуальної машини (принаймні на Sun JVM). Використання консолі може бути нормальним, але, як зазначалося, означає, що ваш код просто не працюватиме при запуску без нього. Натомість розгляньте можливість передачі значень, безпосередньо отриманих з аргументів командного рядка, властивостей системи, файлів властивостей тощо. Принаймні, надайте якусь альтернативу - наприклад, переходьте до консолі, лише якщо значення не було надано як аргумент командного рядка.
Анджей Дойл

1

Я згадував і використовував відповідь formixian, показану вище. Суть полягає у використанні (чорної) консолі cmd для запуску вашої програми Java, як пропонується "ojonugwa ochalifu".

**


0

Це правильно.

Вам доведеться запускати програму за межами Eclipse. Подивіться на панелі конфігурації панелі запуску в Eclipse і переконайтеся, що ви можете помітити опцію, яка говорить про запуск команди в окремій JVM.


0

Якщо ваша IDE використовує javaw замість java, то ця проблема обов’язково трапиться, оскільки javaw по суті є java без вікна консолі.


-1

додайте -console у ваші аргументи програми, щоб запустити консоль OSGi


1
Ви можете пояснити детальніше про це, якщо можливо, приклад?
Галли

Сьогодні я дізнався щось нове, дякую за це. Однак eclipse все одно зчитує параметри з внутрішньої консолі. тож запропоноване рішення не вирішить початкову проблему.
Kiswanij
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.