Compatibilidad con java.io.Console en Eclipse IDE
java-io (10)
Uso Eclipse IDE para desarrollar, compilar y ejecutar mis proyectos Java. Hoy, intento usar la clase java.io.Console
para administrar la salida y, lo que es más importante, la entrada del usuario.
El problema es que System.console()
devuelve null
cuando una aplicación se ejecuta "a través" de Eclipse. Eclipse ejecuta el programa en un proceso en segundo plano, en lugar de un proceso de nivel superior con la ventana de la consola con la que estamos familiarizados.
¿Hay alguna manera de forzar a Eclipse a ejecutar el programa como un proceso de nivel superior, o al menos crear una Consola que la JVM reconocerá? De lo contrario, me veo obligado a ejecutar el proyecto y ejecutarlo en un entorno de línea de comandos externo a Eclipse.
Digamos que su espacio de trabajo de Eclipse es C: / MyWorkspace, usted creó su aplicación java dentro de un proyecto maven MyProject, y su clase principal de Java es com.mydomain.mypackage.MyClass.
En este caso, puede ejecutar su clase principal que usa System.console()
en la línea de comando:
java -cp C:/MyWorkspace/MyProject/target/classes com.mydomain.mypackage.MyClass
NB1: si no está en un proyecto maven, verifique la carpeta de salida en las propiedades del proyecto | Ruta de creación de Java | Fuente. Puede que no sea "objetivo / clases"
NB2: si es un proyecto maven, pero tu clase está en src / test / java, es probable que tengas que usar "target / test-classes" en lugar de "target / classes"
Encontré algo sobre esto en http://www.stupidjavatricks.com/?p=43 .
Y lamentablemente, dado que la consola es definitiva, no puede extenderla para crear un envoltorio alrededor de system.in y system.out que lo haga tampoco. Incluso dentro de la consola eclipse todavía tienes acceso a esos. Eso es probablemente por qué eclipse no ha conectado esto en su consola todavía ...
Entiendo por qué no quieres tener otra forma de obtener una consola que no sea System.console, sin setter, pero no entiendo por qué no quieres que alguien pueda anular la clase para hacer una simulacro / consola de prueba ...
Este link ofrece alternativas para usar System.console (). Uno es usar un BufferedReader envuelto alrededor de System.in, el segundo es usar un Scanner envuelto alrededor de System.in.
Ninguno de los dos es tan conciso como la consola, ¡pero ambos trabajan en eclipse sin tener que recurrir a depurar tonterías!
La razón por la que esto ocurre es porque eclipse ejecuta su aplicación como un proceso en segundo plano y no como un proceso de nivel superior con una consola del sistema.
La solución alternativa que uso es simplemente usar System.in/System.out en lugar de Console cuando se usa Eclipse. Por ejemplo, en lugar de:
String line = System.console().readLine();
Puedes usar:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
Otra opción es crear un método para cerrar ambas opciones y "conmutar" al método System.in cuando la consola no está disponible. El siguiente ejemplo es bastante básico: puede seguir el mismo proceso para cerrar los otros métodos en la Consola (readPassword, format) según sea necesario. De esta forma, puedes ejecutarlo felizmente en Eclipse y cuando se implementa obtienes las características de la consola (por ejemplo, ocultación de contraseña).
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;
}
Parece que no hay forma de obtener un objeto java.io.Console al ejecutar una aplicación a través de Eclipse. Una ventana de consola de línea de comandos no se abre con la aplicación, ya que se ejecuta como un proceso en segundo plano (¿fondo de Eclipse?). Actualmente, no hay un plugin de Eclipse para manejar este problema, principalmente debido a que java.io.Console es una clase final.
Todo lo que realmente puede hacer es probar el objeto de consola devuelto para nulo y continuar desde allí.
Por lo que puedo decir, no hay forma de obtener un objeto de consola de Eclipse. Solo me aseguraría de que consola! = Null, luego JAR y ejecutar desde la línea de comandos.
Puede implementar una clase usted mismo. Lo siguiente es un ejemplo:
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);
}
}
Supongo que desea poder utilizar la depuración paso a paso de Eclipse. Puede ejecutar las clases externamente estableciendo las clases creadas en los directorios bin en el classpath JRE.
java -cp workspace/p1/bin;workspace/p2/bin foo.Main
Puede depurar usando el depurador remoto y aprovechando los archivos de clase integrados en su proyecto.
En este ejemplo, la estructura del proyecto Eclipse se ve así:
workspace/project/
/.classpath
/.project
/debug.bat
/bin/Main.class
/src/Main.java
1. Inicie la consola de JVM en modo de depuración
debug.bat es un archivo por lotes de Windows que se debe ejecutar externamente desde una consola 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
En los argumentos, el puerto de depuración se ha establecido en 8787 . El argumento suspend = y le dice a la JVM que espere hasta que el depurador se adjunte.
2. Crear una configuración de inicio de depuración
En Eclipse, abra el cuadro de diálogo Depurar (Ejecutar> Abrir cuadro de diálogo de depuración ...) y cree una nueva configuración de Aplicación Java remota con la siguiente configuración:
- Proyecto: el nombre de su proyecto
- Tipo de conexión: Estándar (Socket Attach)
- Anfitrión: localhost
- Puerto: 8787
3. Depuración
Entonces, todo lo que tienes que hacer cada vez que quieras depurar la aplicación es:
- establecer un punto de quiebre
- iniciar el archivo por lotes en una consola
- iniciar la configuración de depuración
Puedes rastrear este problema en el error 122429 . Puede resolver este problema en su aplicación utilizando una capa de abstracción como se describe here .