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?


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


¿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 .


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.


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 ".


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.


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).


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".

**


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.


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.


-1

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.