java.io.Console support in Eclipse IDE

95,846

Solution 1

I assume you want to be able to use step-through debugging from Eclipse. You can just run the classes externally by setting the built classes in the bin directories on the JRE classpath.

java -cp workspace\p1\bin;workspace\p2\bin foo.Main

You can debug using the remote debugger and taking advantage of the class files built in your project.

In this example, the Eclipse project structure looks like this:

workspace\project\
                 \.classpath
                 \.project
                 \debug.bat
                 \bin\Main.class
                 \src\Main.java

1. Start the JVM Console in Debug Mode

debug.bat is a Windows batch file that should be run externally from a cmd.exe console.

@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

In the arguments, the debug port has been set to 8787. The suspend=y argument tells the JVM to wait until the debugger attaches.

2. Create a Debug Launch Configuration

In Eclipse, open the Debug dialog (Run > Open Debug Dialog...) and create a new Remote Java Application configuration with the following settings:

  • Project: your project name
  • Connection Type: Standard (Socket Attach)
  • Host: localhost
  • Port: 8787

3. Debugging

So, all you have to do any time you want to debug the app is:

  • set a break point
  • launch the batch file in a console
  • launch the debug configuration

You can track this issue in bug 122429. You can work round this issue in your application by using an abstraction layer as described here.

Solution 2

The workaround that I use is to just use System.in/System.out instead of Console when using Eclipse. For example, instead of:

String line = System.console().readLine();

You can use:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();

Solution 3

You can implement a class yourself. Following is an example:

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

Solution 4

The reason this occurs is because eclipse runs your app as a background process and not as a top-level process with a system console.

Solution 5

Another option is to create a method to wrap up both options, and "fail over" to the System.in method when Console isn't available. The below example is a fairly basic one - you can follow the same process to wrap up the other methods in Console (readPassword, format) as required. That way you can run it happily in Eclipse & when its deployed you get the Console features (e.g. password hiding) kicking in.

    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;
    }
Share:
95,846

Related videos on Youtube

Ross
Author by

Ross

Updated on February 10, 2020

Comments

  • Ross
    Ross about 4 years

    I use the Eclipse IDE to develop, compile, and run my Java projects. Today, I'm trying to use the java.io.Console class to manage output and, more importantly, user input.

    The problem is that System.console() returns null when an application is run "through" Eclipse. Eclipse run the program on a background process, rather than a top-level process with the console window we're familiar with.

    Is there a way to force Eclipse to run the program as a top level process, or at least create a Console that the JVM will recognize? Otherwise, I'm forced to jar the project up and run on a command-line environment external to Eclipse.

    • OneWorld
      OneWorld almost 8 years
      Also see stackoverflow.com/questions/26470972/… I identified System.out and System.in to be sufficient for my use case and abondaned using System.console().
    • Abhigyan
      Abhigyan almost 7 years
      I exported the project as the runnable jar, but i'm still getting console null error
  • Aaron Spalding
    Aaron Spalding about 13 years
    I don't think that you would be able to read passwords with password masking that way.
  • dma_k
    dma_k almost 13 years
    ... and one need to handle IOException, which is not thrown in case of Console.readLine().
  • Matt Lyons-Wood
    Matt Lyons-Wood about 12 years
    I'd also put a pause at the end of that batch file so you can see any error messages that flash up before it closes.
  • marknuzz
    marknuzz about 12 years
    This is the last straw for me. If I have to do all of this just to debug, I am switching back to Netbeans. So many unfixed bugs and UI annoyances in Eclipse it is not even funny.
  • Laplie Anderson
    Laplie Anderson about 10 years
    @Nuzzolilo, this is just for remote debugging. You can debug locally in eclipse without all of that.