When it comes to critising programming languages, Java seems to take the top spot for being the baddest. This is widely seen on the InterTubes, like here, and here.
But does a 'bad' language mean that it'll die a relatively quick death?
To find out, let's take a look at the etymology of an older computer language, C. C has been a systems programming language that has been around the last 40 years. The last revision to the C standard was 10 years ago, and even without moving with the times, the language is still going strong - last I heard, it is still the language of choice for 40% of Open Source developers.
Does that mean that people have stopped complaining about pointers, easy-to-write buffer overflow errors, memory leaks, having to declare all variables up front before code, etc, etc, and other quirks about the language?
I suspect not. So why still C?
Simple - it works. And I suspect the same can be said with Java.
Furthermore, it's silly to argue about Java's merits and drawbacks, because that's really missing the forest for the trees. While the most visible part about Java is the undoubtedly the language, but the true technology of Java is not in the language, but the virtual machine itself. The JVM as it stands today, is a fast, abstract machine that you can plug any languages into, and is able to operate at speeds comparable to natively compiled binaries.
Like most programmers, we do enjoy bitching about peculiarities of a language once in a while, but for people who hate Java with a passion, maybe you need to get your head checked. A language is merely a medium of expression; and a computer language is one specifically used to express program behaviour. Normally, the choices are either to learn it well and avoid the pitfalls, or find a better medium of expression.
So seriously, if you don't like Java, there is a cure. Stop. Using. It.
I'll let you in on a secret to programming languages; there are only two types of languages in this world - languages that people complain about, and languages that nobody uses (Stroustrup said so). So in an obtuse manner, the vast majority of people who criticises about Java are only reaffirming its popularity.
Which is precisely why I can't see Java going the way of dinosaurs. Raving incessantly against it, ironically only helps boost its reputation, albeit in a weird, backhanded-kind of way.
Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts
Saturday, June 05, 2010
Tuesday, February 12, 2008
Command Line Parsing using JFlex
What started out as a small set of commands for a tool I'm writing is slowing growing unwieldy to have to warrant enough repetitious code to parse the command line manually, and to wade through lines of
Rather than having to deal with the unwieldy mess of buggy, manual coding using an ad-hoc mixture of Regular Expressions and
Barring the initial learning curve, certainly having the lexical analyzer certainly makes life much easier, by automatically breaking down the command string into tokens each, without having to intervene to deal with handling white spaces and separators and such. A simple example for a lexical analyser that breaks up commands and arguments looks something like this:
The example should hopefully be simple enough not to cause a 'cringe factor' or the need to refer to the Dragon Book.
There are 3 different sections in JFlex's definition file, separated by
The second section, is a list of definitions and directives that tells JFlex what to do. In this case, I've told JFlex to generate the the output to a file called
The last section is where you define the grammar that helps the generated scanner code to discern what is a token, and in my case, what type of a token it is. In my example, rule 1
It must be noted that ordering is important. If I actually swapped the order of rule 2 with 1, because numbers will match the
The next thing to do is to actually create a actual token class, which is called Yytoken by default. An example of a typical
To test it, you can write a simple harness to read from
That's probably a really basic tutorial in using JFlex, and to learn all of it probably requires having more of RTFM, but in the meantime, have fun in processing your command line!
if/else or switch statements (Don't you preach to me about the virtues of using the Command design pattern, for it is still unwieldy because it does not handle the parsing of arguments even the hash saves you from having long branching segments of code, which I don't mind. In my opinion, it's visually easier for me using folds, rather than to have file fragmentation of one command per file.)Rather than having to deal with the unwieldy mess of buggy, manual coding using an ad-hoc mixture of Regular Expressions and
StringTokenizers, I decided to start using a lexical analyzer instead. The one that I'm using is called JFlex, which is probably the most popular (or only?) one around.Barring the initial learning curve, certainly having the lexical analyzer certainly makes life much easier, by automatically breaking down the command string into tokens each, without having to intervene to deal with handling white spaces and separators and such. A simple example for a lexical analyser that breaks up commands and arguments looks something like this:
/** The lexer for scanning command tokens. */
%%
%class CommandLexer
Parameter = [:jletterdigit:]+
WhiteSpace = [ \n\t\f]
%%
[:digit:]+ { return new Yytoken(Integer.parseInt(yytext())); }
{Parameter} { return new Yytoken(yytext()); }
{WhiteSpace} { /* Ignore Whitespace */ }
"-" { return new Yytoken('-'); }
"," { return new Yytoken(','); }
The example should hopefully be simple enough not to cause a 'cringe factor' or the need to refer to the Dragon Book.
There are 3 different sections in JFlex's definition file, separated by
'%%' symbols. The first section is straightforward, it just allows you to include whatever that you wanted to include in the generated file.The second section, is a list of definitions and directives that tells JFlex what to do. In this case, I've told JFlex to generate the the output to a file called
'CommandLexer[.java]'. Subsequently, the next two lines allows me to put in what I defined as 'WhiteSpace' or 'Parameter'.The last section is where you define the grammar that helps the generated scanner code to discern what is a token, and in my case, what type of a token it is. In my example, rule 1
'[:digit:]+', matches 1 or more number and transforms that into a token, rule 2, matches what I call a parameter (which has either one or more digits or letters, and contains at least 1 letter in it). Rule 3, just tells the scanner to ignore all WhiteSpace characters, while Rule 4, 5 indicates what I define as separators, in my case the characters '-' and ','.It must be noted that ordering is important. If I actually swapped the order of rule 2 with 1, because numbers will match the
{Parameter} rule first, the [:digit:]+ rule will never match. JFlex will tell you that if that's the case (highlighted in red below):
Reading "commandlexer.jflex"
Constructing NFA : 16 states in NFA
Converting NFA to DFA :
.....
Warning in file "commandlexer.jflex" (line 13):
Rule can never be matched:
[:digit:]+ { return new Yytoken(Integer.parseInt(yytext())); }
7 states before minimization, 5 states in minimized DFA
Old file "CommandLexer.java" saved as "CommandLexer.java~"
Writing code to "CommandLexer.java"
The next thing to do is to actually create a actual token class, which is called Yytoken by default. An example of a typical
Yytoken.java file looks somewhat like this:
/** A single scanner token. */
public class Yytoken {
public boolean is_separator = false;
public boolean is_int = false;
public boolean is_token = false;
public char separator;
public String token = null;
public int value = 0;
/** Default for range separator. */
public Yytoken(char c) {
is_separator = true;
separator = c;
}
public Yytoken(int value) {
is_int = true;
this.value = value;
}
public Yytoken(String token) {
is_token = true;
this.token = token;
}
public String toString() {
if (is_separator) return "Range Token("+separator+")";
else if (is_int) return "Int Token("+value+")";
else return "Token ("+token+")";
}
}
To test it, you can write a simple harness to read from
stdin:
/** Test class to try out the command lexer. */
public class UseCommandLexer {
public static void main(String args[]) throws Exception {
CommandLexer command_lexer = new CommandLexer(System.in);
Yytoken token = null;
do {
token = command_lexer.yylex();
System.out.println("token = " + token);
}
while (token!=null);
}
}
That's probably a really basic tutorial in using JFlex, and to learn all of it probably requires having more of RTFM, but in the meantime, have fun in processing your command line!
Friday, January 18, 2008
Tab Completion for Vim (Updated)
As I've said before, I wasn't really satisfied with the original tab completion script, which didn't perform all the possible search completion combinations vim is capable of. After accidentally overwriting my existing
As with before, the script has to utilize existing auto-completion script, and the additional changes on my script now makes tab 'intelligently' to perform completion on incomplete methods and fields, rather than having only to be able to do so only at the start of the dot
Here's the script that you'll need to copy and paste into your
.vimrc file, I just thought it was high time I remedied the incomplete implementation of tab completion for vim to work properly with Java.As with before, the script has to utilize existing auto-completion script, and the additional changes on my script now makes tab 'intelligently' to perform completion on incomplete methods and fields, rather than having only to be able to do so only at the start of the dot
('.'). Also, if tab occurs at locations where it doesn't fit the profile of a method or field (i.e, it's not in the pattern of 'package.class.methodname_or_fieldname', where package is optional), it will try to use vim's built-in keyword completion (<C-X><C-P>) instead.Here's the script that you'll need to copy and paste into your
.vimrc:
" Modified tab completion. It works fine now.
function! My_TabComplete()
let line = getline('.') " curline
let substr = strpart(line, -1, col('.')+1) " from start to cursor
let substr = matchstr(substr, "[^ \t]*$") " word till cursor
if (strlen(substr)==0) " nothing to match on empty string
return "\<tab>"
endif
let bool = match(substr, '\.') " position of period, if any
if (bool==-1)
return "\<C-X>\<C-P>" " existing text matching
else
return "\<C-X>\<C-U>" " plugin matching
endif
endfunction
autocmd BufNew,BufRead *.java inoremap <tab> <C-R>=My_TabComplete()<CR>
If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #2: Using exuberant-ctags
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto Bracketing for Java
Tuesday, October 02, 2007
Profiling in Java
In any Computer Science lectures that has anything to do with the topic of profiling, the story of how
What makes it such a good story, is probably because that a quarter of the performance drag hinges on just a single line of code. But before anybody starts embarking on their own witch hunts in looking for such performance bottlenecks, I'll like to remind you about the other story that CS students are always told, the one related to by the 'Grandpa of Computer Science', Donald Knuth, on premature optimization:
This is why profilers are handy. It tells you where exactly the performance bottlenecks are, rather than trying to make wild guesses about them before implementation, and writing obscured optimizations that will most likely add unnecessary complexities and potentially introduce more bugs.
Profiling in Java
The equivalent of '
An example syntax for invoking a profiler looks like:
Hprof allows for the measurement of CPU cycles, Memory Usage, and Thread traces, so it is absolutely helpful in determining the state of the application, and sometimes gives you additional insights in bug tracking either from traces, or locate the sources of memory leaks. I won't provide more usage details, but a more comprehensive run through of hprof can be found here.
Understanding Hprof's output
The various columns indicates the following:
Using Hat

While I've known
So make sure you have the following parameter for binary format activated:
If you read the bug report, you'll realise I wasn't the only person being annoyed that such a trivial bug isn't fixed for such a long time, not to mention the immense confusion that it's caused. Perhaps someone should start renaming
'awk' got a performance boost by 25% just using gprof never fails to not be mentioned. The story ends with finding that offending loop code that accounted for most of the wasted computational time.What makes it such a good story, is probably because that a quarter of the performance drag hinges on just a single line of code. But before anybody starts embarking on their own witch hunts in looking for such performance bottlenecks, I'll like to remind you about the other story that CS students are always told, the one related to by the 'Grandpa of Computer Science', Donald Knuth, on premature optimization:
'There is no doubt that the 'grail' of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.'This is important, because the first thing that a programmer should look out for, is correctness. You can always speculate about where performance bottlenecks are, but unless you're using something as obvious as a 'Bubblesort', you can't really be sure where the major performance overhead is going to come from.
This is why profilers are handy. It tells you where exactly the performance bottlenecks are, rather than trying to make wild guesses about them before implementation, and writing obscured optimizations that will most likely add unnecessary complexities and potentially introduce more bugs.
Profiling in Java
The equivalent of '
gprof' in the GNU/C world is named, unimaginatively, as 'hprof' for Java, a natural succession from the letter 'h' to 'g', just as the 'C' language is the successor to 'B'. Gosh, aren't Computer Scientists lacking in imagination!An example syntax for invoking a profiler looks like:
java -agentlib:hprof[=options] ToBeProfiledClass
Hprof allows for the measurement of CPU cycles, Memory Usage, and Thread traces, so it is absolutely helpful in determining the state of the application, and sometimes gives you additional insights in bug tracking either from traces, or locate the sources of memory leaks. I won't provide more usage details, but a more comprehensive run through of hprof can be found here.
Understanding Hprof's output
SITES BEGIN (ordered by live bytes) Sat Sep 29 13:46:46 2007
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 18.07% 18.07% 387192 16133 390912 16288 302005 java.lang.String
2 12.04% 30.11% 258144 16134 258144 16134 302007 com.sun.tools.javac.util.List
3 6.14% 36.25% 131512 2 131512 2 301079 com.sun.tools.javac.util.Name[]
4 6.12% 42.36% 131088 1 131088 1 301080 byte[]
5 6.12% 48.48% 131072 1 131072 1 301679 byte[]
6 3.06% 51.54% 65536 1 65536 1 301187 byte[]
7 3.06% 54.59% 65536 1 65536 1 301677 byte[]
8 1.60% 56.19% 34240 428 34800 435 302250 byte[]
9 1.11% 57.30% 23856 426 23856 426 302248 com.sun.tools.javac.code.Symbol$MethodSymbol
The various columns indicates the following:
- rank - self explanatory
- percent self - percentage of memory taken up
- percent accum - cumulative percentage of memory taken up from rank 1 to rank N
- live vs. alloc'ed - the actual objects that are active vs. objects still held in memory i.e, not garbage collected
- stack trace - The corresponding id given to a thread trace that is holding onto a reference to this memory
- class name - The type of object the memory is allocated
'ctrl-\' in Linux and 'ctrl-break' in Windows.Using Hat
Hat or (JHat as is now called in Java 6 SE), is a profile analysis tool which allows you to have make relational queries (like SQL) of memory usage, which is something that's pretty interesting.
( Screenshot of Hat's Web Application Interface )
While I've known
Hat for quite a while already, but I have given up a long time ago for not managing to get it to work. But recently, there is a new bug report filed for the error, which explains the reason for my problem is because Hat only being able to read the binary format output from hprof.So make sure you have the following parameter for binary format activated:
java -agentlib:hprof=agentlib:hprof=heap=sites,format=b ToBeProfiledClass
If you read the bug report, you'll realise I wasn't the only person being annoyed that such a trivial bug isn't fixed for such a long time, not to mention the immense confusion that it's caused. Perhaps someone should start renaming
JHat as 'asshat' instead!
Saturday, September 15, 2007
Cscope with Vim for finding Java symbols
Cscope, like ctags, allow you to find symbols in your source from multiple files in your project easily. While it was originally developed for C (easily inferred by the name), the project has extended to cover a number of other languages as well, Java included.
Before you mistake cscope as a rehash of my tip on using exuberant-ctags, let me explain why scope is different. Cscope has semantic knowledge of the Java as a language, and understands when you are looking for a symbol (a variable or method definition), and other useful search functions, like finding out other methods that invoke method you want, or listing all the methods definition uses.

The advantage of semantic knowledge is that when you are looking for a variable or method, you won't be sent to some uncharted parts of your code, such as within your comments, just because there is a piece of text that matches the name.
To use it with vim as the default editor, you'll have to set that in the environment in your shell (where the following is for bash) if it isn't set already:
You'll need to generate a list of files for cscope to be able to generate cross references to. This is easily done by using the find command in the root directory where your java files are found:
There are ways to allow cscope to run within vim instead of the other way round, but while I managed to do it after a bit of experimentation, I did find that I've used it with cscope invoking vim more commonly, whenever I need to fire it up and look for the methods or variables that I want from time to time. Happy cscoping!
Before you mistake cscope as a rehash of my tip on using exuberant-ctags, let me explain why scope is different. Cscope has semantic knowledge of the Java as a language, and understands when you are looking for a symbol (a variable or method definition), and other useful search functions, like finding out other methods that invoke method you want, or listing all the methods definition uses.

(Image of Cscope in Action)
The advantage of semantic knowledge is that when you are looking for a variable or method, you won't be sent to some uncharted parts of your code, such as within your comments, just because there is a piece of text that matches the name.
To use it with vim as the default editor, you'll have to set that in the environment in your shell (where the following is for bash) if it isn't set already:
export EDITOR=/usr/bin/vim
You'll need to generate a list of files for cscope to be able to generate cross references to. This is easily done by using the find command in the root directory where your java files are found:
find ./ -name *.java > cscope.files
cscope.files is the filename that cscope will read each time it starts up, so make sure you adhere to that.There are ways to allow cscope to run within vim instead of the other way round, but while I managed to do it after a bit of experimentation, I did find that I've used it with cscope invoking vim more commonly, whenever I need to fire it up and look for the methods or variables that I want from time to time. Happy cscoping!
If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #2: Using exuberant-ctags
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #4: Using 'tab' for Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto-Bracketing Within Vim
Friday, September 07, 2007
The Dangers of Auto-boxing in Java
This is one of the those subtle bugs that I have unwittingly coded in because of the inherent laziness that is afforded by Autoboxing, a feature that was available with Java 1.5 onwards.
What auto-boxing means, is that Java will perform conversion between primitives to its Object equivalents and vice-versa for you automatically, rather than via the
However, because of the inherent non-obvious assumptions made, it can lead to subtle bugs that can be hard to spot. It did for me, especially when it was enmeshed in a part of a long stretch of code.
To give an illustrative example of the bug:
As said, this example will only compilable with 1.5 and above, so take note if you want to compile it. Java will 'intelligently' determine the type of the primitive variable and turn them into objects for you, making it easier to use primitives with utility libraries such as
Caught the bug yet?
If you haven't, let me show you what Java has implicitly converted the code into through Autoboxing:
I've shown the offending lines in blue. As you should know, Java objects of the same value but of different types are fundamentally not equal, i.e.
That is a good reminder to look out and be careful of pitfalls like this, one which costed me 2 hours to find. Next time I'll think twice and look triply hard before relying on Autoboxing to do the right thing again!
What auto-boxing means, is that Java will perform conversion between primitives to its Object equivalents and vice-versa for you automatically, rather than via the
new() constructor way that you do traditionally. However, because of the inherent non-obvious assumptions made, it can lead to subtle bugs that can be hard to spot. It did for me, especially when it was enmeshed in a part of a long stretch of code.
To give an illustrative example of the bug:
import java.util.*;
public class Test {
static HashMap<Integer,String> hm = new HashMap<Integer, String>();
public static void main(String args[]) {
byte b = 1;
hm.put(1, "Hello World");
String s = hm.get(b);
System.out.println("The result is: " + s);
}
}
As said, this example will only compilable with 1.5 and above, so take note if you want to compile it. Java will 'intelligently' determine the type of the primitive variable and turn them into objects for you, making it easier to use primitives with utility libraries such as
java.util.HashMap. But if you run it, you're going to find that it is printing 'null' rather than 'Hello World'.Caught the bug yet?
If you haven't, let me show you what Java has implicitly converted the code into through Autoboxing:
...
public void main(String args[]) {
byte b = 1;
hm.put(new Integer(1), "Hello World");
String s = hm.get(new Byte(1));
System.out.println("The result is: " + s);
}
...
I've shown the offending lines in blue. As you should know, Java objects of the same value but of different types are fundamentally not equal, i.e.
Integer(1) != Byte(1). That is the sole culprit of the problem, which is being masked by using Auto-boxing.That is a good reminder to look out and be careful of pitfalls like this, one which costed me 2 hours to find. Next time I'll think twice and look triply hard before relying on Autoboxing to do the right thing again!
Monday, September 03, 2007
Vim Remade: Working on Java with all of Netbeans' features
The title sounds like a bold claim, given that the comparison sounds like one between apples and oranges. While vim will probably never incorporate some features that Netbeans as an IDE has, fundementally, both are text editors, and do share some commonalities that we can contrast and compare with.
I started using Netbeans because I needed a good RAD tool for building Swing GUIs. Matisse, the graphical GUI builder built-in with Netbeans, came to me as an impressive tool that allows for an easy and intuitive way of building graphical frontends.
It wasn't just Matisse that impressed me. Netbeans had bucketloads of other editing features that weren't available with vim, which left me feeling less satisfied than I originally was. But even as I toyed with the idea of dumping vim for Netbeans, trying to unlearn my keystrokes, getting used to context switches from fidgeting with menus and alternating between the mouse and keyboard again just wasn't worth the trouble.
That had been my primary reason for writing the various Java Tips for Vim, which I hope becomes useful to other Java developers who code primarily in vim. To do a rehash on my current list of tips:
Intellisense (or Syntax Completion)
The first and foremost feature that I'd really liked in Netbeans is 'intellisense', or the auto-completion of syntax. It makes coding much a less tedious effort, saving up time and the trouble of having to constantly look up API calls via Javadoc.
Tabbing for Syntax Completion
As nice as it is, Netbeans' auto completion sometimes does not work as intended, either suggesting wrong stuff, or nothing at all. But what irks me most is that auto-suggestion can be intrusive and uncalled for at times.
However the existing keystroke sequences
Auto-bracketing
Related to automatic syntax completion, is the ability to complete brackets, braces and curly braces, etc. While I haven't completely figured out the way to foolproof auto-bracketing quotes and other quirks with my solution, this solution will probably be one of those 'keep in view' hacks that I'll try to improve in the future.
API Lookup using ctags
Netbeans has a preview window that pops up relevant API information for Java, something that is lacking in vim. The closest alternative I know, is achieved by using ctags to look up API calls, saving a bit of a hassle by directing you to the right source file automatically.
Automatic compilation via Ant
Allows you to do a compilation with just the
Code Folding
Reduces visual clutter from your code, by folding them up according to methods, or other large blocks of code that makes semantic sense to you.
After these adjustments I've made, it is really starting to feel that vim is now customized sufficiently to have roughly the same amount of usability as Netbeans for Java specific development, so it will probably be while later before I revisit these issues again. Hopefully the tips will be as useful for you as I've found it!
I started using Netbeans because I needed a good RAD tool for building Swing GUIs. Matisse, the graphical GUI builder built-in with Netbeans, came to me as an impressive tool that allows for an easy and intuitive way of building graphical frontends.
It wasn't just Matisse that impressed me. Netbeans had bucketloads of other editing features that weren't available with vim, which left me feeling less satisfied than I originally was. But even as I toyed with the idea of dumping vim for Netbeans, trying to unlearn my keystrokes, getting used to context switches from fidgeting with menus and alternating between the mouse and keyboard again just wasn't worth the trouble.
That had been my primary reason for writing the various Java Tips for Vim, which I hope becomes useful to other Java developers who code primarily in vim. To do a rehash on my current list of tips:
Intellisense (or Syntax Completion)
The first and foremost feature that I'd really liked in Netbeans is 'intellisense', or the auto-completion of syntax. It makes coding much a less tedious effort, saving up time and the trouble of having to constantly look up API calls via Javadoc.
Tabbing for Syntax Completion
As nice as it is, Netbeans' auto completion sometimes does not work as intended, either suggesting wrong stuff, or nothing at all. But what irks me most is that auto-suggestion can be intrusive and uncalled for at times.
However the existing keystroke sequences
<C-X><C-U> for syntax completion in vim can be a bother sometimes, and easier way is to map the <tab> key to contextually determine whether you want syntax suggestion, or a tab itself.Auto-bracketing
Related to automatic syntax completion, is the ability to complete brackets, braces and curly braces, etc. While I haven't completely figured out the way to foolproof auto-bracketing quotes and other quirks with my solution, this solution will probably be one of those 'keep in view' hacks that I'll try to improve in the future.
API Lookup using ctags
Netbeans has a preview window that pops up relevant API information for Java, something that is lacking in vim. The closest alternative I know, is achieved by using ctags to look up API calls, saving a bit of a hassle by directing you to the right source file automatically.
Automatic compilation via Ant
Allows you to do a compilation with just the
:make command. Of course you can bind it to the <F5> key and that would make it feel just as the same as an IDE.Code Folding
Reduces visual clutter from your code, by folding them up according to methods, or other large blocks of code that makes semantic sense to you.
After these adjustments I've made, it is really starting to feel that vim is now customized sufficiently to have roughly the same amount of usability as Netbeans for Java specific development, so it will probably be while later before I revisit these issues again. Hopefully the tips will be as useful for you as I've found it!
Wednesday, August 22, 2007
Vim Tips for Java #6: Auto-Bracketing Within Vim
One of the things that I've learnt that Netbeans is able to do, was the ability to perform auto-bracket completion. For a while, I was missing that nifty little feature when I reverted back to using vim, and I tried tweaking around with vim to provide the same feature, only with limited success. Only after writing my tip on tab-completion had I realised that I have already a complete solution in providing for auto-brackets.
The following script I have will allow me to detect whether if I really wanted a closing bracket/brace or whether if has already been inserted previously by the auto-bracketing script, and hence I should skip it, by checking what the current character on the cursor right is. So here's what's needed to be added to your
While it is neither the cleanest nor the most elegant way, but it replicates faithfully with what Netbeans does. Unfortunately, this solution will still not work for quotes and double-quotes because of the nature of the
The following script I have will allow me to detect whether if I really wanted a closing bracket/brace or whether if has already been inserted previously by the auto-bracketing script, and hence I should skip it, by checking what the current character on the cursor right is. So here's what's needed to be added to your
.vimrc in order for it to work:
autocmd Filetype java imap ( ()<left>
function! My_BracketComplete()
let char = strpart(getline('.'), col('.')-1, 1)
if (char == ")")
return "\<Right>"
else
return ")"
endif
endfunction
autocmd FileType java inoremap ) <C-R>=My_BracketComplete()<CR>
autocmd Filetype java imap { {}<left><cr><cr><up><tab>
function! My_BraceComplete()
let char = strpart(getline('.'), col('.')-1, 1)
if (char == ")")
return "\<Right>"
else
return "}"
endif
endfunction
autocmd FileType java inoremap } <C-R>=My_BraceComplete()<CR>
While it is neither the cleanest nor the most elegant way, but it replicates faithfully with what Netbeans does. Unfortunately, this solution will still not work for quotes and double-quotes because of the nature of the
'imap' command, which will make vim go into a non-terminating loop. So if some of you have thought of a better way to do this, do share it with me by posting your solution on my blog.If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
Vim Tips for Java #2: Using exuberant-ctags
Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
Vim Tips for Java #4: Using 'tab' for Syntax Completion
Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
Friday, August 17, 2007
Vim Tips for Java #5: Folding Code Blocks to prevent Visual Blindness
When dealing with large source files, there is a tendency for visual blindness to kick in, where there is just too much code everywhere for you to find things like the start of a method or a particular important segment of code, in a sea of random visual clutter.
With Vim (6.0 onwards I think), there is support for concept of folding, which helps to segregate your code into meaningful chunks visually, expanding and collapsing the folds as you work. There are a number of keystrokes to learn, so if you are new to folding you might want to read a tutorial like
this one (link to linux.com).

Initially I wanted a way to automatically generate folds for me based on the type of source code I'm working on, and a nice answer I have found is the SimpleFold plugin from Eigenclass, which helps in creating folds automatically for you by matching the source file with certain patterns.
I believe that it does automatic folding for Ruby quite well, but because of the syntax structure of Java, folding using plain regex probably doesn't fully match my requirements (it doesn't handle the treatment of inner classes and methods that well, and mistakes certain variable declarations as methods) so I tend to use manual folding instead, which is done by using the command:
While folding by default on vim looks alright, but I find SimpleFold's display with brackets and indentation much better for differentiation between class definitions and methods, so I decided to shamelessly copy the formatting part of SimpleFold's code for my own nefarious use instead (Copy to
With the change, you'll see a difference between the indentation of the methods within the folds, and the number of lines within square brackets. And now, it looks much better!

With Vim (6.0 onwards I think), there is support for concept of folding, which helps to segregate your code into meaningful chunks visually, expanding and collapsing the folds as you work. There are a number of keystrokes to learn, so if you are new to folding you might want to read a tutorial like
this one (link to linux.com).

Initially I wanted a way to automatically generate folds for me based on the type of source code I'm working on, and a nice answer I have found is the SimpleFold plugin from Eigenclass, which helps in creating folds automatically for you by matching the source file with certain patterns.
I believe that it does automatic folding for Ruby quite well, but because of the syntax structure of Java, folding using plain regex probably doesn't fully match my requirements (it doesn't handle the treatment of inner classes and methods that well, and mistakes certain variable declarations as methods) so I tend to use manual folding instead, which is done by using the command:
:set foldmethod=manual
While folding by default on vim looks alright, but I find SimpleFold's display with brackets and indentation much better for differentiation between class definitions and methods, so I decided to shamelessly copy the formatting part of SimpleFold's code for my own nefarious use instead (Copy to
.vimrc):
function! Num2S(num, len)
let filler = " "
let text = '' . a:num
return strpart(filler, 1, a:len - strlen(text)) . text
endfunction
function! FoldText()
let sub = substitute(getline(v:foldstart), '/\*\|\*/\|{{{\d\=', '', 'g')
let diff = v:foldend - v:foldstart + 1
return '+' . v:folddashes . '[' . Num2S(diff,3) . ']' . sub
endfunction
set foldtext=FoldText()
With the change, you'll see a difference between the indentation of the methods within the folds, and the number of lines within square brackets. And now, it looks much better!

If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #2: Using exhuberant-ctags
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #4: Using 'tab' for Syntax Completion
- Vim Tips for Java #6: Auto-Bracketing Within Vim
Tuesday, August 14, 2007
Vim Tips for Java #4: Use 'Tab' for Syntax Completion
If you have used my previous tip for automatic syntax completion, you might find that using the
<CTRL-X><CTRL-U> keystrokes to perform omni-completion can sometimes get quite frustrating after a while. To help address this annoyance, I wrote a little vim function to use the <tab> button to perform syntax completion instead.The nice thing about that, is the function does contextual scanning to see if you actually want a
<tab> or omni-completion to be performed by scanning the token at immediately before the cursor when the <tab> button is pressed.Put these lines into your
.vimrc:
function! My_TabComplete()
let substr = strpart(getline('.'), col('.'))
let result = match(substr, '\w\+\(\.\w*\)$')
if (result!=-1)
return "\<C-X>\<C-U>"
else
return "\<tab>"
endfunction
autocmd FileType java inoremap <tab> <C-R>=My_TabComplete()<CR>
The specific pattern I'm looking for in this case is 'objectOrClass.' or 'objectOrClass.incompleteMethodName', but do feel free to change to fit your own needs. Also, if you are using the keyword replacement keystroke
<CTRL-P> rather than vjde, you should modify the script to return '\<C-P>' instead.If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #2: Using exuberant-ctags
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto-Bracketing Within Vim
Saturday, August 11, 2007
Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for syntax completion
As much as I like vim, Netbeans trumps it when we talk about automatic syntax completion. Because of the vast amount of API that is present for the Java platform, the ability of having auto-suggestion for syntax is a godsend.
While things like looking up an API call while you are in the thick of coding are irritating, the effects of such distractions are often much more profound. A recent article by the New York Times suggests that such interruptions do not just result in the reduction of your efficiency, but increase the chances of making mistakes as well.
In vim 7.0, there is a facility that allows you to have auto-suggestion capabilities, which comes bundled for a number of languages like Ruby, Python, etc, but however not for Java. If you have followed my tip in using exhuberant-ctags for Java, the modification will allow vim to have primitive syntax completion capabilities, by using
The problem with this approach, is that it performs 'dumb' keyword completion of previous matching patterns, rather than the 'intelligent' contextual syntax completion. This can lead to mistakes in suggestions, which can be rather frustrating.
For true contextual syntax completion, there are a few plugins out there works for Java. By and large, they aren't as polished as Netbeans, but still, they are quite functional and and usable. I've used a number of them in the past before, and the one that I reccomend for you to install is vjde.
While the plugin is quite usable, the documentation can use some working on. The default instructions requires you to install it in the
1) Download the latest copy of vjde;
2) Uncompress the downloaded .tar archive;
3) Copy the
In order to use the completion, use the
While things like looking up an API call while you are in the thick of coding are irritating, the effects of such distractions are often much more profound. A recent article by the New York Times suggests that such interruptions do not just result in the reduction of your efficiency, but increase the chances of making mistakes as well.
In vim 7.0, there is a facility that allows you to have auto-suggestion capabilities, which comes bundled for a number of languages like Ruby, Python, etc, but however not for Java. If you have followed my tip in using exhuberant-ctags for Java, the modification will allow vim to have primitive syntax completion capabilities, by using
<CTRL-P>. In this case, it tries to match a word you've typed with all the keywords found in ctag's tag file.The problem with this approach, is that it performs 'dumb' keyword completion of previous matching patterns, rather than the 'intelligent' contextual syntax completion. This can lead to mistakes in suggestions, which can be rather frustrating.
For true contextual syntax completion, there are a few plugins out there works for Java. By and large, they aren't as polished as Netbeans, but still, they are quite functional and and usable. I've used a number of them in the past before, and the one that I reccomend for you to install is vjde.
While the plugin is quite usable, the documentation can use some working on. The default instructions requires you to install it in the
/etc/vim global directory, something I'm not willing to do in fear of of messing up my default installation's configurations. Fortunately instructions for local installation is pretty straightforward:1) Download the latest copy of vjde;
2) Uncompress the downloaded .tar archive;
3) Copy the
autoload/, compiler/, doc/, plugin/, syntax/ directories to your $HOME/.vim/ directory;In order to use the completion, use the
<CTRL-X><CTRL-U> keystroke, which will provide you with an Intellisense-like syntax completion capability. Have fun with your new syntax-completion capability, and keep on vimming!If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #2: Using exuberant-ctags
- Vim Tips for Java #4: Using 'tab' for Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto-Bracketing Within Vim
Friday, August 10, 2007
Passing variable length arguments to a Java Method
It is not well known fact that Java can actually handle variable length arguments passed to its method calls. This is achieved by using "..." operator in argument signature of your method declaration, commonly used when certain arguments to the method are optional. Here's a simple code example to illustrate its usage:
Internally, the number of arguments is actually statically determined by
As you can see, I've only declared 1 method called
/** Testing variable arguments passing. */
public class Varargs {
public static void main(String args[]) {
myMethod("Hello");
System.out.println();
myMethod("Hello", "again", "world!");
}
public static void myMethod(Object ... args) {
System.out.println("You have passed in " + args.length + " arguments ");
for (Object o : args) {
System.out.println(o);
}
}
}
'myMethod', and have passed an arbitary number of arguments to it, which would have in the past generated a compiler error telling me that the method signatures I've used are not present. But in this case (with Java 1.5 and above), it compiles and produces the following output:The "..." operator does require you must have at least 1 or more arguments, but while you can pass a
You have passed in 1 arguments
Hello
You have passed in 3 arguments
Hello
again
world!
null to it, the compiler will generate some output to warn you to be explicit in your variable typing.Internally, the number of arguments is actually statically determined by
'javac' compiler, and converted to an object array for processing, so there are limitations in the sense that it is not truly dynamic, but just a compilation convenience method that can save you from writing multiple method signatures for different permutations of the same method call.If you like reading this, you may also enjoy:
Wednesday, August 08, 2007
Vim Tips for Java #2: Using exuberant-ctags
ctags is a great tool for programmers. It creates an index to your source code to allow you to trawl through them for cross referencing. While the way it works doesn't look as snazzy as nicely formatted javadoc output like Netbeans, it does its job well enough for you to read up a field or method definition whenever you need it. You'll need to install exuberant-ctags separately, which you can find on its website.A requirement of using ctags, is that you'll need to have the Java source code available for ctags to parse them into a searchable index file for vim. It's usually located in your Java distribution at
$JAVA_HOME/src.zip. Unzip the file, and in my case I extract it into the $JAVA_HOME/share directory I've created. Then run exuberant-ctags:
exuberant-ctags -R --language-force=java -f.tags /opt/sun-jdk-1.5.0.08/share/
This command generates a
'.tags' index file in my home directory. The next thing to do is to allow vim to be able to locate and use the index file. Add the following line into your .vimrc:
autocommand FileType java set tags=~/.tags
This should now allow you to jump to any definition in the Java API, whenever you need to look it up from your code. To test this, create a Java file and put some code in it:
public class TestClass {
String s = new String();
}
Move your cursor under to the word 'String' and press
ctrl-]. Voila, you should now be reading into the source of.. not just yet, it is not java.lang.String! Most probably it is showing you some other classes that has a String object in its field, which is probably not what you are looking for. To cycle through the remaining matches, use the command mode instruction ':ts' to go through the list of matching tags and select the right item you want.You might also want to be familiarized with the navigation keystrokes, by doing a
':help' on ':ta', ':ts', 'CTRL-L', 'CTRL-]', which may be useful.A few dissatisfactions that I still have with this method:
1) It doesn't allow me to read the embedded javadocs in code as html. It will be pretty cool if this feature can be linked to lynx and shown in a window within vim, but I'm not certain if it is possible;
2) I don't believe that searching through all the miscellaneous fields of other classes is the best way of using ctags. There may be something that I have not mastered that permits me to fully utilize the power of ctags yet.
I'll be looking further to see if I can learn more tips on using ctags, but in the meantime, if anybody have any suggestions for improvement, I'll appreciate if can leave a suggestion, thanks!
If you like reading this, you may also enjoy:
- Vim Tips for Java #1: Build Java files with Ant Automatically
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #4: Using 'tab' for Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto-Bracketing Within Vim
Monday, August 06, 2007
Vim Tips for Java #1: Build Java files with Ant automatically
Ant is a great tool for compiling large projects with a large number of Java files. It is the equivalent of
Add the following lines in your .vimrc:
As long the
All that's remaining is just to type
'make' for C, but is customised specifically for Java. While the support for make works with vim by default, certain changes have to be made for vim in order to make it work properly for Java.Add the following lines in your .vimrc:
autocmd BufRead *.java set efm=%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
autocmd BufRead set makeprg=ant\ -find\ build.xml
As long the
build.xml file is in the parent directory of where the Java files you are working on is located, vim will be able to locate it, compile the changed files and inform you of where the compilation errors are.All that's remaining is just to type
:make, and you now have automatic compilation from within Vim!If you like reading this, you may also enjoy:
- Vim Tips for Java #2: Using exuberant-ctags
- Vim Tips for Java #3: Use Omni-Completion (or Intellisense) for Automatic Syntax Completion
- Vim Tips for Java #4: Using 'tab' for Syntax Completion
- Vim Tips for Java #5: Folding Code Blocks to Prevent Visual Blindness
- Vim Tips for Java #6: Auto-Bracketing Within Vim
