System.console () devuelve nulo

78

Yo estaba usando readLinede BufferedReaderconseguir entrada / nueva contraseña del usuario, pero quería enmascarar la contraseña de modo que estoy tratando de utilizar java.io.Consolela clase. El problema es que System.console()regresa nullcuando se depura una aplicación en Eclipse. Soy nuevo en Java y Eclipse, ¿no estoy seguro de si esta es la mejor manera de lograrlo? Hago clic derecho en el archivo de origen y selecciono "Depurar como"> "Aplicación Java". ¿Hay algún trabajo alrededor?

Galos
fuente
1
También vea stackoverflow.com/questions/26470972/… Identifiqué System.outy System.inpara ser suficiente para mi caso de uso y aboné el uso System.console().
OneWorld

Respuestas:

33

Este fragmento de código debería funcionar:

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

Mientras prueba en Eclipse, la entrada de su contraseña se mostrará en claro. Al menos, podrás probar. Simplemente no escriba su contraseña real durante la prueba. Guárdelo para uso en producción;).

formixiano
fuente
¿Debería su readLinemétodo enrollado a mano cerrar el BufferedReaderen un bloque finalmente (o intentar con recursos)?
Andrew Swan
No, porque eso cerraría la coincidencia de la System.insecuencia y no se podrían realizar más lecturas después.
formixian
Sí, es extraño que este flujo se pueda cerrar; Esperaba que fuera una operación no operativa.
Andrew Swan
9

También encontré este problema al intentar escribir una aplicación de línea de comandos simple.

Otra alternativa para crear su propio objeto BufferedReader desde System.in es usar java.util.Scanner de esta manera:

import java.util.Scanner;

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

String s = in.nextLine();

Por supuesto, esto no será un reemplazo directo de Console, pero le dará acceso a una variedad de funciones de entrada diferentes.

Aquí hay más documentación sobre Scanner de Oracle .

MonoPapel
fuente
7

Según los documentos :

Si la máquina virtual se inicia automáticamente, por ejemplo, mediante un programador de trabajos en segundo plano, normalmente no tendrá una consola.

Vincent Ramdhanie
fuente
1
Esta respuesta me lleva a descubrir que si está ejecutando Gradle con el demonio habilitado, no podrá obtener una consola en sus tareas de Gradle. Ejecutar mi tarea de Gradle con '--no-daemon' permite el acceso a la consola.
whitespy
Esto me sucedió cuando usé drip ( github.com/ninjudd/drip ) para una herramienta de línea de comandos. ¡Ups!
George L
7

Según la API :

" Si la máquina virtual se inicia desde una línea de comando interactiva sin redirigir los flujos de entrada y salida estándar, su consola existirá y normalmente estará conectada al teclado y la pantalla desde la que se inició la máquina virtual. Si se inicia la máquina virtual automáticamente, por ejemplo mediante un programador de trabajos en segundo plano, normalmente no tendrá una consola ".

Emad Aghayi
fuente
4

Recibí este mensaje de error al ejecutar la aplicación desde Netbeans. A juzgar por las otras respuestas, parece que esto sucede cuando ejecuta su aplicación desde un IDE. Si echas un vistazo a esta pregunta: Intentando leer desde la consola en Java , es porque

La mayoría de los IDE utilizan javaw.exe en lugar de java.exe para ejecutar código Java

La solución es usar command line/terminalpara obtener el Console.

Ojonugwa Jude Ochalifu
fuente
1

Creo que en las configuraciones de ejecución para Eclipse, puede configurar si asignar una consola o no; asegúrese de que esto esté marcado. (Ha pasado un tiempo desde que usé Eclipse, así que me temo que no puedo dar instrucciones específicas).

Si eso no funciona, entonces algo que definitivamente hará este trabajo es iniciar su aplicación en modo de depuración y luego conectarse al proceso con Eclipse. Busque "depuración remota de eclipse" si no está seguro de cómo hacerlo.

Además, en general es una mala idea exigir que se asigne una consola, ya que esto afecta mucho la flexibilidad de su aplicación, como acaba de descubrir. Muchas formas de invocar Java no asignarán una consola, y su aplicación no se puede utilizar en estos casos (lo cual es malo). Quizás, alternativamente, podría permitir que se especifiquen argumentos en la línea de comando. (Si está probando la entrada de la consola específicamente, entonces es lo suficientemente justo, pero sería potencialmente útil para las personas poder invocar su aplicación desde scripts y / o en servidores sin cabeza, por lo que este tipo de diseño flexible es casi siempre una buena idea . A menudo también conduce a un código mejor organizado).

Andrzej Doyle
fuente
sí, es solo para mi propósito de depuración, los usuarios obtendrán un script de shell o un archivo bat. ¿No es bueno usar la consola? Si es así, ¿cuál es la mejor manera
Galos
Por cierto, toda la búsqueda de depuración remota habla sobre el servidor web, pero no estoy creando una aplicación web. este es un Java simple. ¿Podría ser una mejor forma de enmascarar la contraseña?
Galos
Puede depurar remotamente cualquier proceso de Java, simplemente agregue, por ejemplo, -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000a los argumentos de la VM (al menos en Sun JVM). Usar la consola puede estar bien, pero como se señaló significa que su código simplemente no funcionará cuando se inicie sin una. En su lugar, considere pasar valores directamente de los argumentos de la línea de comandos, propiedades del sistema, archivos de propiedades, etc. Al menos proporcione alguna alternativa, por ejemplo, vaya a la consola si no se proporcionó un valor como argumento de la línea de comandos.
Andrzej Doyle
1

Me referí y utilicé la respuesta de formixian que se muestra arriba. El punto es usar la consola cmd (negra) para ejecutar su programa Java como sugirió "ojonugwa ochalifu".

**

Park JongBum
fuente
0

Eso es correcto.

Tendrá que ejecutar la aplicación fuera de Eclipse. Mire los paneles de configuración del lanzador dentro de Eclipse y vea si puede detectar la opción que dice ejecutar el comando en una JVM separada.

Stephen C
fuente
0

Si su IDE usa javaw en lugar de java, entonces este problema seguramente ocurrirá ya que javaw es esencialmente java sin ventana de consola.

Cerveza de jengibre
fuente
-1

agregue -console en los argumentos de su programa para iniciar la consola OSGi

Kane
fuente
1
¿Puede aclarar más sobre esto si es posible un ejemplo?
Galos
Hoy aprendí algo nuevo, gracias por eso. Sin embargo, eclipse aún lee los parámetros desde dentro de la consola interna. por lo que su solución propuesta no resolverá el problema original.
Kiswanij