Sunday, May 24, 2009

Passing '\n' (new-line) on command line in Java

Can we pass a new-line ('\n') character or any other escape sequence via command line in Java?

One of our visitors (Vivek Athalye) asked this in response to the article -
Tricky use of static initializer block. Thought of posting the answer as a separate article to increase the chances of it reaching to a wider range of audience.

The answer to the query is NO. The question arises, if you pass the same escape sequence programmtically, it works fine, so why doesn't it work well when passed via command line? For example: System.setProperty("line.separator", " Bye!\nBBye!"); will work fine, but if try to do the same via command line as (java -Dline.separator=" Bye!\nBBye!" ClassName) then '\n' will be treated as two distinct ASCII characters ('\' and 'n') and not as a single escape sequence new-line Unicode character.

This behavior was logged as a
bug on Sun's Bug Database on Oct 31, 2003. But, it was closed saying 'not a bug' on Nov 05, 2003. The reason given is that interpretation of text passed on command line is a shell specific stuff and it is not reasonable to expect that to work in lines with the handling of escape sequences by any particular programming language.

It's not something to do with Java as even if you pass a command line argument having '\n' to a C program, it will be treated as two distinct ASCII characters only and not as a escape sequence.

What stops a shell to interpret escape sequences is that escape sequences are represented differently in different programming languages - like '\n' is actually a single character Unicode character whereas in C it's a two-character ASCII sequence having a different meaning because of the preceding '\' character. So, on a system which requires to run both Java and C programs, which convention should the shell use? Tomorrow, if we see any other representation of escape sequence by some other programming language, how will the already developed shell will cope up with that? Hence, shell plays it straight and simply passes everything written on command line as ASCII character sequences without giving any special meaning to any particular sequence. Fair enough, I believe.

Liked the article? Subscribe to this blog for regular updates. Wanna follow it to tell the world that you enjoy GeekExplains? Please find the 'Followers' widget in the rightmost sidebar.



Vivek Athalye said...

As you've mentioned, its not possible for shell to interpret the escape sequences. And I didn't expect it do so.

But when we compare C and Java there is 1 basic difference. C programs are executed directly by OS, where as Java programs are executed by JVM/JRE. So the shell passes command line arguments to JVM(java.exe), which in turn passes them to our program. So isn't it possible for java.exe to parse the arguments before executing our Java program?

Probably they wanted to keep the behavior same as C, thats why they didn't parse it. Any idea?

Thanks & Regards,
- Vivek

Geek said...

Maybe yes. But, to me it looks like the designers of Java didn't think of making the JVM do the parsing of the command line arguments because they probably didn't feel a need to have this behavior. They might have thought that in case of a need, developers can do it programmatically by using the setProperty() method of the System class - probably a cleaner and better maintainable approach.

Another probable reason, they might have wanted to keep the JVM code as compact as possible having only the indispensable kernel of the virtual machine and moving all possible clutter to system libraries or extensions.

My views for sure as we can only speculate about it unless, maybe, any of the Java Designers themselves come out and tell us the reason(s) they thought of (I don't know if any such text is already public?). BTW, it's been a nice discussion and I guess it would of some help to our visitors. Thanks again for your active participation. Keep visiting/posting!