Thursday, August 23, 2007

FindBugs

Inspired by Josh Bloch and Bill Pugh's Java Puzzlers talk at Google, Java Puzzlers, episode VI, I decided to use FindBugs and analyze some core Java libraries we wrote and used at one of my previous employments. Here are some of the findings: Commons: 675 classes, 505 bugs (98 bad practice, 27 correctness, 96 malicious code vulnerability, 14 multithreaded correctness, 207 performance, 63 dodgy). Messaging: 31 classes, 21 bugs (9 bad practice, 8 malicious code vulnerability, 3 performance, 1 dodgy) Services: 239 classes, 78 bugs (5 bad practice, 4 correctness, 35 malicious code vulnerability, 1 multithreaded correctness, 26 performance, 7 dodgy) Content management: 637 classes, 577 bugs (38 bad practice, 14 correctness, 72 malicious code vulnerability, 3 multithreaded correctness, 382 performance, 68 dodgy)

Example bugs include:

Bad attemnpt to compute absolute value of signed 32-bit hashcode:

indexPrimary +=  Math.abs(this.getStoragePrimary()
  .hashCode()) + SEP;
Why? If the hash code is equal to Integer.minValue() then the result will be negative as well.

Impossible cast (ouch!):

ArrayList list=new ArrayList();
setChoices((DateDatum[])list.toArray());
Possible null reference dereference for internalConnetion:
try {
  if(internalConnetion == null) {
    throw new TransactionManagerException("...");
  }
  ...
  } catch(Exception e) {
    throw new TransactionManagerException(
      e.getMessage(), e);
  } finally {
    if (internalConnetion.getDepth() < 1) {
Nullcheck of value previously dereferenced:
if (accountId.equals(internalAccount)) {
  permissions.add(new AllPermission());
  return permissions;
}
if (accountId == null) {
  return permissions;
}
This last comparison for null is redundant since, if true, it would have already raised an exception.

Method invokes inefficient Boolean constructor:

return new Boolean(false);
Boolean objects are immutable, there's no need to create a new instance; use Boolean.valueOf(...) instead.

Method invokes inefficient new String(String) constructor:

String path = new String("");
Method concatenates strings using + in a loop:
for(int i = 0; i < (hash.length / 2); i++) {
  rtnValue += Integer.toHexString(x);
}
Inefficient use of keySet iterator instead of entrySet iterator:
Set keySet = headers.keySet();
Iterator iterator = keySet.iterator();
while(iterator.hasNext()) {
  String value = (String) headers.get(key);
}
May expose internal representation by incorporating reference to mutable object:
public void setMethods(Hashtable methods) {
  this.methods = methods;
  FunctionsContainer.getLogger().info("Loaded " +
    methods.size()+" methods");
}

This code stores a reference to an externally mutable methods object into the internal representation of the object. Storing a copy of the object would have been much safer.

It's always a good idea to statically analyse your code once you're done with it. It's not going to render it bug free but it certainly helps. Oh, and while I'm at it, go get yourself a copy of Java Puzzlers book; it helps avoiding some very dark corners you might not have been aware of.

Sunday, August 19, 2007

xkcd

A webcomic of romance, sarcasm, math, and language by Randall Munroe. Check it.

Friday, August 17, 2007

parkour


I didn't know that parkour was so popular until I saw the video above. This is a short definition from Wikipedia:

Parkour (sometimes abbreviated to PK) or l'art du déplacement (English: the art of displacement) is recreational activity of French origin, the aim of which is to move from point A to point B as efficiently and quickly as possible, using principally the abilities of the human body.

Astonishing eh? Now my traceurs, summon your spidery powers and displace yourselves!

Tuesday, August 14, 2007

cURL

If you are not already using it, I suggest you start using cURL. cURL, or Client for URLs, or see URL comes in two flavours, a command line tool for getting and sending files using URL syntax and a library, libcurl, for use by other programs. It supports more than a dozen protocols (FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE, LDAP), cookies, proxy tunneling, transfer resume, authentication (Basic, Digest, NTLM, Negotiate, kerberos...), SSL certificates, HTTP uploads, progress meter, speed limit, you name it. Here's some examples:

Upload a file as multipart/form-data plus extra params to a URL: curl -F upload=@localfilename -F press=OK [URL]

Use an agent of your choice: curl -A "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]

Get the last 500 bytes of a document: curl -r -500 http://www.get.this/

ftp upload through a proxy: curl --proxytunnel -x proxy:port -T localfile ftp.upload.com

Read and write cookies from a netscape cookie file: curl -b cookies.txt -c cookies.txt www.example.com

Download resume: curl -C - -o file http://www.server.com/

cURL is in Flash Player 9, Mac OS X, F-Secure and IBM's BOINC among others. Interfaces exist for most major as well as other more obscure languages. Unfortunately, the javacurl interface supports a small subset of cURL's features and is not well tested.

Friday, August 10, 2007

cloning adventure

Once I wanted to create clones of tree nodes, naming the clones of node say A as A-Copy-1, A-Copy-2, etc. My first thought was using the parent's child-count property and start counting copies from that value onwards. However, if the nodes are A, A-Copy-1 and A-Copy-2, when A-Copy-1 gets deleted the child-count becomes 2 and if that is used you get the same name as one of the existing children. Then I thought I would simply iterate through all children named A-Copy-i, for i = 1 to child-count, and create clones whenever that name was for take. That would reuse slots created by previous deletions but would make distinguishing the new nodes impossible. This was easily fixed by finding the maximum copy count of A and start creating clones after that so, if A-Copy-4 and A-Copy-6 sibling nodes are left in the tree, any new copies would be named as A-Copy-7, A-Copy-8 etc. That way you would always get a nice continuous set of cloned nodes in the tree. Even if you wanted to clone A-Copy-i node, that would quite naturally become A-Copy-i-Copy-j. I decided to use regular expressions to look for <node name>-Copy-<copy count> sibling nodes. That gave the extra benefit of having the copy count part available by means of a capturing group. To force any metacharacters in the node name to be treated like ordinary characters, I preceded every single character in the name with backslashes:

StringBuffer escapedNodeName = 
  new StringBuffer(nodeName.length()*2);
for (int i = 0; i < nodeName.length(); i++) {
  escapedNodeName.append('\\').append(nodeName.charAt(i));
}
RE exp = new RE(escapedNodeName.toString() + "-Copy-([1-9]\\d*$)");
This failed miserably! Guessed why? It is quite alright to escape a metacharacter, but it is another kettle of fish when "escaping" ordinary characters. When this code was used on a tree which had numbers in names, the escaped digits became backreferences and the match failed. I hastily changed the escaping part of the code to enclose the name within a quote (\Q and \E). No sooner had I done this than I realised that even that had its own fallacy: what if the node name had a \E in it? Proper quoting required some more effort:
StringBuilder escapedNodeName = 
  new StringBuilder(nodeName.length() * 2);
escapedNodeName.append("\\Q");
slashEIndex = 0;
int current = 0;
while ((slashEIndex = nodeName.indexOf("\\E", current)) != -1) {
  escapedNodeName.append(nodeName.substring(current, 
                                            slashEIndex));
  current = slashEIndex + 2;
  escapedNodeName.append("\\E\\\\E\\Q");
}
escapedNodeName.append(nodeName.substring(current, 
                                          nodeName.length()));
escapedNodeName.append("\\E");
Thankfully this is made available as java.util.regex.Pattern.quote(String) method since Java 1.5.

Tuesday, July 31, 2007

freemarker vs velocity

There is a feature comparison sheet on Freemarker site, listing why Freemarker is a superior templating engine to Velocity. Not very objective you may say, but there are certain features, like the use of JSP tags and XML transformation capabilities that Velocity lacks. Freemarker more closely follows the MVC pattern, in that Velocity allows you to change the model from the view (e.g. request.session.removeAttribute(attrName) will remove the attribute) while Freemarker does not let you do so. I do not think that any of the two engines is a serious contender for a full blown web engine to be honest, but I would be interested to see some speed statistics, especially for uses in high volume messaging applications where every single message would need to go through the engine. Furthermore, the quest for separation of the model from the view reminds me of that other quest for over-validation. I don't want templates that change my model, sure, but I don't want to have to recompile my classes just because an email wants person.surname in addition to person.name in it, either.

Friday, July 13, 2007

alfresco

There's been an interesting development in the area of Enterprise Content Management (ECM) space during the last couple of years, that goes by the name Alfresco. I've been meaning to write about it for quite some time when I got tickled again by one recent email of theirs, announcing the release of Alfresco Community 2.1. For those of you not familiar with it who still think that ECM is all about boring apps organizing boring docs made by boring cos, think again. Alfresco is open source based on best-of-breed technologies, including Spring, Hibernate, Lucene, jBPM, MyFaces, Rhino etc and providing a rich set of interfaces like CIFS/SMB, FTP, WebDAV, Web Services, REST. It was started in 2005 by John Newton co-founder of Documentum and John Powell, former COO of Business Objects and has since been downloaded some 600,000 times and installed at more than 12,000 sites and going strong. I wonder what the implications will be on the likes of IBM (FileNet), Interwoven and Oracle.

Wednesday, July 11, 2007

life is beautiful

Here's an idea: after the usual spam checks, pass every incoming email automatically through Snopes, as a last resort to spam prevention. These emails are hard to detect as the senders have usually added their very own personal comment, and most of the time they are among your trusted friends. Therefore, you not only stumble upon the email in your inbox instead of it being automatically thrown to your trash can, you are fooled by the sender into actually opening and reading the email before you realise it is yet another hoax. Worse still, you have to go manually through Snopes, just in case it is real. Life is beautiful is one of these hoaxes that was first circulated on the Internet back in 2002 and got sent to me again... today.

Wednesday, July 04, 2007

bumptop

Vista has surely spiced up things a bit, as far as user interfaces go, and Mac's new Leopard is really beautiful. But how about rethinking the whole desktop and the ways one can interact with it? Anand Agarawala has done exactly that, with BumpTop, a physically-based, casual user interface that pushes the desktop metaphor with physics, piles and the pen. For the more inclined, Anand's Masters Thesis (Enriching the Desktop Metaphor with Physics, Piles and the Pen) and a paper co-authored with Ravin Balakrishnan say it all.

Monday, June 04, 2007

alpha, beta, gamma, loves you, delta

We all know the various software development cycles. Alpha used to be mostly for internal testing. Beta represented versions released to the wider public for the purpose of real world testing. Nobody dared call their version Gamma out of fear that people would confuse that with their Gamma Phi Beta sorority. So most stuck to Beta, using enumerations to denote post-Beta releases like Beta I (or 1), Beta II (or 2) etc. Then Microsoft figured that an operating system was entitled to a brand new concept of post-Beta test cycles and, that system being Windows, they probably were right. So they started issuing what they euphemistically called Release Candidate versions to the public. Of course, you could always find some very peculiar versioning conventions if you looked hard enough, like Knuth's TeX ever approaching Pi numbers. By the time open source software became de facto, and releases were mostly Web Server software updates, Release Candidate sounded too formal and rigorous, so Gamma became the new Beta II. Now Flickr calls one of its recent releases "LOVES YOU", instead of Delta, Gamma II, Super/Post Candidate Release I, signalling a new era of version naming standard. Who knows what the next release will be? WILL MARRY YOU perhaps.