java.io.Console is finally here!

One of the most popular feature requests for J2SETM in recent times has been the request to improve console support and provide a way to enter passwords with echo disabled. Developers know this feature 4050435 as it has been skulking in the Top 25 RFEs list for some time.

The good news is that the feature has made it into Mustang thanks to Xueming Shen. It went into b57 and should show up be on the download site later today. The feature adds java.io.Console which provides methods to read lines and passwords from the console. It also provides useful methods to write formatted strings to the console too. Here's a little taster that prompts user to enter a password that is at least 8 characters in length. The password is not echoed to the console as it is entered.


static final int MIN_PASSWORD_LENGTH = 8;

char[] password;
do {
    password = System.console().readPassword(
      "Enter password (minimum of %d characters): ", MIN_PASSWORD_LENGTH);
} while (password.length < MIN_PASSWORD_LENGTH);


System.console() is used to obtain the unique Console for the Java virtual machine. There may not be a console of course - it depends on the platform, and also on how the Java virtual machine was started. If there isn't a console then the console() method returns null (the above code fragment doesn't check for this).

The readPassword method writes the prompt and reads the password. The prompt is provided as a format string and an argument list. If you've used the formatted printing support that was added in J2SE 5.0 then you'll recognize this.

Another thing about this code fragment is that it leaves you with a password in a character array. As with anything sensitive you don't want to have this in memory for a long time so it's good to zero the array as soon as you can.

So if you develop applications that need to access a character based console then you should find java.io.Console very useful (and very simple to use).

Comments:

That's nice, but I'd really like System.getConsole() instead of System.console().

Posted by guest on October 21, 2005 at 08:22 AM PDT #

Another great feature that fits right in here would be to add a detach() method that can be used to detach from the console and send the application to the background. This could be extremely useful for servers that need to obtain a password (e.g., the PIN needed to access an SSL keystore) to perform some of their processing. Even without the need to read from the console, the ability to background an application would be incredibly useful.

Posted by guest on October 22, 2005 at 06:55 AM PDT #

Does this include getch() like functionality? (which as I believe was part of the RFE)

Posted by Donald Guy on October 23, 2005 at 02:29 AM PDT #

62.216.120.250 - For methods that return something that isn't a boolean then the general convention nowadays is to name the method with a noun or a noun phrase. When there are methods to set and get an attribute then setAttribute/getAttribute would be usual. Also if the class is a bean the bean-standard for naming setters and getters would have to be used but this isn't the case here.

Donald - this doesn't include curses-like getch. Rather this is more like getpass(3C) - sorry.

Posted by alanb on October 23, 2005 at 06:35 AM PDT #

Alan, I don't think that's true, about the general convention nowadays. I see a lot of code, and the only code which consistently violates the getxx/setxx convention is Sun's (see java.util.regex, java.util.concurrent, ProcessBuilder). I think you should change the names of console(), writer(), and reader().

Posted by Keith Lea on October 24, 2005 at 01:08 AM PDT #

Is this convention something that applies to java.lang.System only? Since you have System.currentTimeMillis(), and System.nanoTime() with no 'get'. I also think it should be called getConsole(). The new java.awt.SystemTray has getSystemTray(), but no setSystemTray(). The same goes for java.awt.Desktop.getDesktop(), and java.awt.SplashScreen.getSplashScreen().

Posted by guest on October 24, 2005 at 01:38 AM PDT #

@alanb:
"... the general convention nowadays..." ... Huh? Since when? Where? Did I miss a memo?

I don't know which Java code you're reading, but the method you describe is certainly not a convention in the known Java world. (You won't make Java code more compact or Ruby/.../C#-like by getting rid of set/get strings...).

If Sun wants to ditch the Beans convention, then it should say so and use it in all of it's code instead of doing a halfassed job like that (the examples given in previous comments show that this convention isn't known to everyone at Sun, like java.awt.SplashScreen.getSplashScreen(),...)

Posted by murphee on October 24, 2005 at 04:42 AM PDT #

Alan,

You say that there is no getch() functionality, so I assume all input is buffered, even if we use System.console().reader().read(). That is, a Java application will not see any input until the user hits Return...

Is this correct, or can we in fact get unbuffered chars by using the reader()?

This should probably be stated explicitly in the javadoc.

I'm surprised, but not unhappy, I don't think, that there are versions of readLine() and readPassword() that take prompt arguments. I wouldn't expect anything returned by the System class to have utility methods on it.

Posted by David Flanagan on October 24, 2005 at 04:42 AM PDT #

People: if you harass a Sun engineer about Sun's own naming conventions, you'll only make yourself look foolish!

This is a long-settled matter. I griped about this back when the java.nio API was being developed for Java 1.4. I got over it. AWT and Swing use JavaBeans style conventions. Many other APIs, especially the lower-level "system" APIs like I/O stuff do not.

Posted by David Flanagan on October 24, 2005 at 04:47 AM PDT #

Since nobody uses console I/O anymore anyway, I don't care so much that Sun got this one completely wrong. Missing out on the major points of the RFE and providing a very specific high-level API when all that was needed were a couple low-level methods. Turn off/on character echo. Read characters in an unbuffered manner. After all these years, we get a half baked "solution" with no useful methods. Oh well. Command-line programs were obsolete 15-20 years ago, so it won't matter.

Posted by SWP on October 24, 2005 at 12:28 PM PDT #

I wouldn't be so sure that noone is using Console IO anymore. In the production world it is a fact of life. There are simply applications which require extremely fast interaction, no mouse and type-ahead. We have applications which definitely need to be console applications. We have written alot of it in Swing, but it's been expensive for us. We almost moved to C for that very reason. I welcome Sun's move in this area.

Posted by David Armstrong on October 24, 2005 at 04:52 PM PDT #

David - thanks for reviewing. I agree it would be better to clarify so that there isn't the expectation that the reads on the Reader are unbuffered.

Posted by alanb on October 24, 2005 at 06:45 PM PDT #

David Flanagan, you're foolish for not holding them to a long standing convention. The word "console" isn't even a verb!

Posted by Bob Lee on October 25, 2005 at 12:15 AM PDT #

Agree with the above posters. Please use getters and setters everywhere. Programmers and IDE's alike expect them everywhere and an API that sometimes uses them and sometimes not is guaranteed to infuriate its users. I'm not saying it's good or bad, just that it's a standard (set by Sun itself!!!) and that it should be respected.

Posted by Cedric on October 25, 2005 at 12:19 AM PDT #

It was a standard set for beans.

This isn't a bean.

IDEs expect beans to have methods that start with get and set.

This isn't a bean.

This isn't a bean.

Thanks, Sun, for this class. It is sorely needed in my area of work.

Posted by J on October 25, 2005 at 04:58 AM PDT #

J, good for you! ;) From Sun's Java naming conventions: "Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized." (http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html#367) They even provide this example: getBackground() "console" isn't a verb.

Posted by Bob Lee on October 25, 2005 at 06:09 AM PDT #

Actually, console is a verb. You might console someone when they are upset, to make them feel better. Maybe that's what this method does, it consoles and massages your system. If so, the Javadoc needs to be updated.

Posted by Keith Lea on October 25, 2005 at 08:55 AM PDT #

And right afterward, it breaks the rule by adding another rule about length, which is an attribute of things like strings:

<code>A method that returns the length of something should be named length, as in class String.</code>

There is, in my view, quite an area of room for growth in the conventions. The convention rules state that they should not be followed slavishly.

The engineers that designed this class felt that it should be named console(), possibly because of its clean succinctness, possibly for other reasons. Some agree with it (like me), others don't.

However, the decision has been made.

Posted by J on October 26, 2005 at 12:26 AM PDT #

As someone already wrote, since when did System become a JavaBean? And additionally, console() is a STATIC method, so even if it was renamed getConsole() it wouldn't be considered a property getter by any IDE anyway. Please think before writing.

Posted by Nils on October 26, 2005 at 01:49 AM PDT #

Instead of providing useless java.io.Console with readPassword(), please, provide just low-level functionality to enable/disable echo and way to read single characters without buffering. Utility methods to read e.g. passwords would be trivial to create above that functionality.

Posted by Dissatisfied on October 26, 2005 at 03:33 AM PDT #

I think getXXX() and setXXX() is junk. I'd rather have the c++ convention any day.

Posted by radu on October 26, 2005 at 08:48 PM PDT #

I think the math validator on message posts has a bug or something; I'm really sure I couldn't have missed the answer to 0+14 !

Posted by radu on October 26, 2005 at 08:49 PM PDT #

I've noticed also that "System.console" gets the MSDOS charset right on Windows platforms, something that doesn't happen automatically with "System.out". For example, on French versions of Windows, the default file encoding is Cp1252 for Windows applications, but for console applications, it's Cp850. The result of which is that it's very difficult to set up console applications to output localised text in a readable way (direct calls with accented characters and System.out produce garbage unless you wrap it in an OutputStreamWriter and know how to determine which encoding is correct for the execution context of the application: o/s, windows/dos/IDE, locale, ...).

Posted by Christopher Brown on October 27, 2005 at 11:18 PM PDT #

"Please think before writing." Nils, please read before writing, especially before making assinine comments like that. No one has said it should be getConsole() because of the bean convention. We want consistency, not hacks to make methods look like fields: http://crazybob.org/2005/10/i-heart-getters-and-setters.html

Posted by Bob Lee on October 29, 2005 at 01:07 AM PDT #

Yes, please give us the ability to disable echos, and it becomes simple to do the password thing, as well as other richer effects. Also I realize this isn't going to be a rich curses style api, but at least the ability to clear the console screen would be nice as a minimum.

Posted by Alex on October 29, 2005 at 11:59 AM PDT #

A plattform independant clearScreen()?? would be nice, have not found any so far.

Posted by Henrik Östman on October 30, 2005 at 06:49 PM PST #

Does this class have a funcationality like 'kbhit()' which is available in C?

Posted by Minkoo Seo on November 02, 2005 at 02:20 AM PST #

When / where did the get/set convention become the defacto standard for POJOs? The convention was meant for javabean containers so that they could introspect properties in a standard way. How did this ever become the standard way to write a java class? Imagine what would happen if you prefixed every single word in your english vocabulary with get / set :-). And finally, in my opinion, the get / set convention violates encapsulation bigtime, and code written following this convention tends to be verbose and badly encapsulated. I see the lack of encapsulation as \*the\* biggest issue with most java codebases

Posted by sander on November 08, 2005 at 09:06 PM PST #

Naming arguments aside, and though I'm glad to have this functionality in some form, I completely agree with posters like SWP and Dissatisfied that this is a disappointing form. This is the kind of quick and dirty, go for the 80% and forget the 20% API I'd expect to find in something like PHP (sorry, PHP fans), not the Java core library. The top priority should be providing low-level functionality to enable/disable echo and read single, unbuffered characters. Convenience methods like readPassword() are useful for consistency, and possibly leveraging higher-level platform support, but should be a secondary concern.

Posted by Trevor on November 13, 2005 at 03:40 AM PST #

I agree with Dissatisfied. This Console thing is right now essentially useless. Listen to your users and provide the wanted low-level functionality!

Posted by Useless on November 24, 2005 at 08:21 PM PST #

The least that I hope to get from this new Console is the ability to read single keypresses the moment they occur, without echo or buffering. Reading a password then becomes elementary (and all but superfluous fluff), single keypress responses become a no-brainer, and line editing not much more difficult than that.

Please?! With sugar on top?

Posted by Udo on December 05, 2005 at 02:53 AM PST #

What a disappointment. We have been requesting it for over 5 years - what we want to do is to read password from console with masking!! Even Sun put its effort on JAAS / JCE stuff, they just cannot help any real situation.

Posted by Hue on December 15, 2005 at 11:25 AM PST #

I want to be able to implement NetHack in Java (-: So much for java.io.Console

Posted by Andreas on December 19, 2005 at 06:16 AM PST #

Jeff Friesen's article on JavaWorld includes another example where he prompts a user for a database password.

Posted by guest on January 31, 2006 at 05:58 PM PST #

i just have used your tool, good! but i stil like CloneFinder (now in version 2.02), it is a low cost refactoring tool that quickly finds duplicated code within C, C++, Java and C# programs. http://www.yaodownload.com/software-development/tools-editors/clonefinder/

Posted by joe on April 21, 2006 at 03:41 PM PDT #

i agree with joe

Posted by Gymso on March 07, 2007 at 12:21 AM PST #

Hi, I am looking for a build-in Java IO function retrieve/extract the standard output of some primitive legacy proprietary diagnostic utility similar to "top" which does not support redirection of output/log to a file. I am contemplating of the needs to write a terminal emulation to run on Wyse60 mode in order to display these statistic data properly. Does the java.io.Console class support some of this functionality? Any assistance would be very appreciated. Thanks in advance, Helen

Posted by Helen Trang on April 09, 2007 at 10:14 AM PDT #

Not Sure whether the below link would help, just check out

http://www.javalobby.org/java/forums/t84689.html

Thanks,

Posted by SME Software Solutions on December 11, 2007 at 08:25 PM PST #

"System.console().readPassword" shows error!

[Z:\\pass.java:9: cannot find symbol
symbol : method console()
location: class java.lang.System
password = System.console().readPassword("Enter password (minimum of %d characters): ", MIN_PASSWORD_LENGTH);
\^
1 error

Tool completed with exit code 1
]

Posted by guest on February 07, 2008 at 06:40 PM PST #

Post a Comment:
Comments are closed for this entry.
About

user12820862

Search

Top Tags
Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
News
Blogroll

No bookmarks in folder