Tuesday, October 16, 2007

Money does not float!

Money Doesn't Grow On Trees
Somebody told me the other day, since money is made from paper, and paper comes from trees, actually, money *does* grow on trees! Anyway, I digress.

There's also a software adage that says "money does not float". What this means is that for currency calculations you should never use a 'float', or floating point arithmetic. I bet we've all done it. We automatically think that a double or float will be fine for working with amounts, like money. If the amounts are all whole numbers then a long or int would suffice, but for working with amounts, floating point arithmetic is probably the worst option you can take. But I bet there's probably some of your code, out there, in production, happily purring along - using floats. Well be afraid, be very afraid.

An Example of the Problem
For starters, consider the following. What would the output of the following line of code be do you think?
System.out.println(1.20f - 1.00f == 0.20f);
Go on, take a guess. 'true', or 'false'? That's right, of course it's a trick question, and of course it outputs a big, fat, ugly:
false
That's the problem with floating point arithmetic. It's not precise. If you've got financial code using floats, and you're making decisions in your code based on the type of logic above, you're screwed. :-)

Therein Lies The Rub

So if you're anything like me, and you're not a mathematician, you're thinking "but why?" Glad you asked. It turns out that floating point arithmetic is quirky in computers. It stems from the fact that computers store numbers in binary format. Makes sense I guess. Now on the face of it, this doesn't seem problematic, but take for instance the number "1/3". How do we write that in decimal? To be totally accurate, we would have to write 0.3333333333333 and so on and so forth into eternity. But since we have limited patience and limited paper, we 'approximate' the number. We write as many 3's as we think are important to write. Anything beyond that, who cares, we'll suck it up. But, fact is, it's therefore not a precise number, it's simply an approximation, but in our estimation, an acceptable approximation. If I want 1/3 + 1/3, I'm happy with 0.66, even though the correct answer is 0.6666666 into eternity. In computers, with converting decimal numbers to their binary representation, there are similar problems. For example, there's no exact binary representation for the decimal '0.1'. So what you get is a repeating 0110 0110 0110 0110 up to a point, depending on the bit size. Most computers use a standard called IEEE 754 for representing floating point numbers in binary. With this decimal to binary conversion there are often rounding errors that creep in and depending on the circumstances, this can come back to bite you. I won't go much further into this. Joel On Software gives a great explanation of it with his article on the Excel bug which was influenced by this decimal to binary oddity. Read it here. The point I wanted to bring home, is that using floating point numbers for currency calculations can cause rounding errors depending on what the calculation is and what that translates to in binary.

Let's look at an example:

So why use the darn thing then? Why floating point arithmetic?
Well for one things it's fast. Using floating point arithmetic on computers is apparently a big deal. When you hear computer speed benchmarks referred to as flops, or megaflops, or teraflops, guess what? It's a measure of how many floating point operations can be done per second. Somehow that's a big deal to us geeks. :-)

Big Brother, I mean, Decimal To The Rescue

You've read this far, and you're about to throw your hands up in despair. "What the heck do I do then?" you retort. Indeed. What do we use? Well it seems the best thing to do when working with something like currency, is to work in the lowest unit of that currency and work the conversion magic in the presentation, be that in a user interface or in a paper report. So you do all your calculations in cents, but display the result in $'s. And apparently, a class in Java (and I believe in some other languages) is BigDecimal. BigDecimal doesn't use floating point arithmetic, therefore it is accurate. You may be wondering why we don't just always use this. Well it's a lot slower than floating point arithmetic. So it's a trade-off.

Tuesday, September 11, 2007

Is your VM lazy or eager?

My dad would turn in his grave if I said that sometimes it is actually better to be lazy.

Introduction
We had a strange bug appear on our Suse and Fedora 4 builds today. Our main client product threw a NoClassDefFoundError on a part of the code where it shouldn't have needed to throw that error about the class it was complaining it couldn't find. Basically I used jacob.jar, a very slick little Java-COM bridging library, to do some Windows service interrogation for a health check feature we implemented on our client product. Actually, in this case our client talks to a service but in the context of our entire product suite, the service and the GUI are collectively "the client". Anyway, moving on.

This feature is obviously only necessary on Windows builds, so we don't package the jacob.jar in our non-Windows builds, which was fine because we don't call the potentially offending methods on the non-Windows builds either. Even though there were import statements for these classes, we felt sure that it wouldn't be a problem because those classes are never needed, so naturally they would never be loaded. Or so I ass-u-me'd!

What Tha?!
When our QA guys reported the bug, I felt sure there was another place in our code that tried to load those classes. But after searching the code, I found nothing. Then I assumed that maybe it was the import statements at the top of the class that were causing the problem. So I removed those and fully qualified the class names in the method that was never called. Kaboom! Still complained of NoClassDefFoundError.

Test The Assumption
Okay, so in times like this, it's best to isolate the problem and see whether you can reproduce it with a simple case. So I created 2 classes, MainClass and SomeOtherClass as follows.

Here's MainClass:
package com.test.classloading;

import com.acme.clientlib.SomeOtherClass;

public class MainClass {

static {
System.out.println("Loading MainClass");
}

public void doYourThing() {
System.out.println("Enter doYourThing()");

SomeOtherClass soc = new SomeOtherClass()
soc.doStuff();

System.out.println("Exit doYourThing()");
}

private void doYourOtherThing() {
System.out.println("Enter doYourOtherThing()");

System.out.println("Doing other thing");

System.out.println("Exit doYourOtherThing()");
}

public static void main(String[] args) {
MainClass mc = new MainClass();
mc.doYourThing();
mc.doYourOtherThing();
}
}

And here's SomeOtherClass:
package com.acme.clientlib;

public class SomeOtherClass {

static {
System.out.println("Loading SomeOtherClass");
}

public void doStuff() {
System.out.println("doStuff called");
}
}

As you can see, I have static initializer blocks that indicate when the classes are loaded and initialized.

When I run this test I get the output I expect:
Loading MainClass
Enter doYourThing()
Loading SomeOtherClass
doStuff called
Exit doYourThing()
Enter doYourOtherThing()
Doing other thing
Exit doYourOtherThing()

Ok, so next I removed the call to SomeOtherClass's doStuff() method as follows:
        MainClass mc = new MainClass();
// mc.doYourThing();
mc.doYourOtherThing();

When I run that on Windows I get:
Loading MainClass
Enter doYourOtherThing()
Doing other thing
Exit doYourOtherThing()

So it would appear that SomeOtherClass never gets loaded. Cool! We're all set!

Not so fast
Unfortunately when I ran that same code on the Fedora box (in my case) with Sun JDK 1.5, I got the dreaded NoClassDefFoundError again! What gives?! How can it work on Windows, but not on Linux?! At first we thought it might be compiler inlining optimizations from some static final's we use in our code, but that didn't make sense either, as it would then only be inlined on Windows builds, not Linux builds.

Well as I'm sure you know, when a class is loaded, it must be initialized but it must first be linked before it can be initialized. To link a class it must be prepared, verified, and (optionally) resolved. It seems that in this case, the Windows VM is doing a lazy job of that last step, resolving (i.e. only doing it when it absolutely has to) whereas the Linux VM is being a bit overeager. Okay, so an easy fix then would be to simply move all of that code into a separate class. Then when the general class is loaded, the Windows specific stuff will be elsewhere. No problem. So I changed my code and moved all the jacob.jar dependent code into a separate class. I tested it on Fedora. Worked like a charm. I checked that into CVS, and sat back in the comfort of knowing I'd fixed the bug once and for all... or so I ass-u-me'd.

An annoyingly knowledgeable mate of mine ("YOU KNOW WHO YOU ARE!") pointed out a small catch as per TheOracle(tm), TheSourceOfAllKnowledge(tm)... also known as TheSpec(tm). In particular, he pointed me to the VM spec, section 2.17.1:

"The resolution step is optional at the time of initial linkage. An implementation may resolve a symbolic reference from a class or interface that is being linked very early, even to the point of resolving all symbolic references from the classes and interfaces that are further referenced, recursively."

Yikes! So my fix was really just a band aid! There's every possibility that even though I'd moved the code into another class, some VM implementation might actually try and resolve those classes as well. Ok, well to cut a long story short (er, too late ;-) the best solution for this problem was to simply call the other class I'd created via reflection.

Conclusion
So remember that then. Never assume. Did I say that clearly enough? No? Let me say it again then... NEVER ... ASSUME! When in doubt, check the spec!

There's a reason why there's an acronym called "RTFM".

Wednesday, August 29, 2007

Hoorah for Hudson

Introduction

If you haven't heard yet, there's a neat little build tool (server) called Hudson that is available for free to a good home. I read about Hudson on Glen Smith's blog, and when competent people rave about something I usually sit up and take notice. I believe Hudson was started by Kohsuke Kawaguchi though there are others now involved in development with him. You can read about Hudson here, and download the latest version here.

At my company, we'd gotten by doing manual builds at the appropriate time for whatever the purpose. Sounds horrid, but the fact of the matter was that everything was checked into CVS, so if you needed a build, it was there to be checked out and built. However, as our product suite grew and our developer numbers grew, it was never going to be an ideal situation. Thing is, what to do about it? Cue Hudson.

I installed Hudson and played around with it and found it to be a very competent build server, so I talked my boss into letting me stick it on a dedicated machine, so that we could use it as an interim tool. The idea at that time was to get something more robust, like TeamCity, from Jetbrains. Well that was a few months ago, and we currently have 29 jobs setup on Hudson.

What's so great about Hudson?

Glad you asked. Well a number of things actually. I could go on and on so I'm just going to mention some of the main things:
  1. It's 1 WAR file.
    In case you missed what I just said, I said it's ... one... WAR file. So you drop that into your (in our case) Tomcat webapps root, and you're done. I like that Hudson defaults to creating a .hudson folder in your user home folder. This makes it easy-peasy to upgrade Hudson: simply download a new WAR, nuke the old one and its folder and restart Tomcat. Done. Hudson even comes with a 'Shutdown' feature that will gracefully end any currently executing builds, and prevent new builds from starting until after the restart.

  2. AJAXification.
    Other than the pointless fact that it has buzzword gravity, the AJAX behaviour of Hudson is quite useful. If you're on the home page, builds that are scheduled or busy executing will automatically show up in the sidebar, without the whole page reloading every few minutes. There's AJAX behaviour when you fill in textfields etc. Hudson will prompt you with values for that textfields from existing data in Hudson. That kind of thing. Very useful.

  3. Smart touches.
    You can see that the people who are developing Hudson, also use Hudson, and have an understanding for the needs of a build server. An example is that Hudson exports an environment variable for the build number, while executing a job. So you can tap into that value and use it in marking your deliverables. That way you can track bugs back to a particular build, and do better forensic detective work. We use that build number when closing a bug in Bugzilla.

    Hudson also does its CVS checkout using a datetime limiter i.e. check out this module as at this time. At first this was a bit frustrating. If I checked something into CVS and triggered a Hudson build manually, and the change wasn't in the resulting build because the build servers time was off by a few minutes, so I wondered why on earth Hudson didn't simply take the latest HEAD snapshot. Well, as it turns out, there's a good reason. Thing is, most build servers operate in a team environment and it is quite possible that while Hudson is busy checking stuff out of CVS, somebody else is busy checking stuff in. So using a specific time ensures that it checks out everything as it was at that moment, even if it takes Hudson 5 minutes to check it all out. Of course somebody could also be doing a long check-in that crosses that time moment, but that's a lot less likely since CVS commits are usually quick use cases. Ok, truth be told, Hudsons main purpose is, I think, to run scheduled build jobs, at a time when it is unlikely that developers will be actively committing to CVS.

  4. Master slave functionality.
    Our dedicated build server is actually a bit on the puny side. So I thought to myself "Self, wouldn't it be useful if we could use some of our steroid-taking servers to do some of the build work for us?" And lo and behold, Hudson has the ability to create slave nodes, so your master Hudson build server can farm work off to your slave nodes. We haven't actually set this up yet, mainly because of time constraints, but pretty soon I see that as being a very useful feature for us.

  5. Email notification.
    Hudson lets you know when a build fails. It did bother me that it doesn't let you know when a build succeeds, but then it occurred to me that the idea behind Hudson is to schedule builds, or have them trigger from CVS commits, so really, you only want to know when something goes wrong. Also, if a build has failed, then succeeds, it emails you once to let you know that all is back to normal.

  6. RSS Feeds.
    You can pull RSS feeds for all the projects, so to check the latest build and result of a build you simply use your RSS browser. Click on that link and you go straight there. Neat!
So far the only real downside that has impacted us is that you have to checkout modules on a branch, not a tag. For some reason it can't handle tags. After some research I found that this is actually a bug, and that prior to build 1.65 it could handle tags. It's already logged as a bug here though there's no fix estimate at the time of writing this post.

Conclusion
There are many other useful touches to Hudson that make it quite an impressive tool for something that is free, as in beer. We have all of our products now configured to build on Hudson and we have dependencies defined between projects, so that if we make a change to a core component, dependent components build immediately after the core component builds, and that way we detect API breakages very quickly. It should be very easy to hookup Ant test scripts to also run, since they'll be part of the overall build, so hopefully in the near future we have that configured too. I certainly know that our QA guys are much happier having a website they can go to for the latest stuff, and one that has us all on the same page when cross-referencing bugs with bug fixes, and their purported fix build number.

Give it a try and drop me a comment with your comments, good or bad.

Thursday, July 19, 2007

Ideas for posts

  • A quick primer on merging from a branch to the head of a CVS module with Tortoise CVS.
  • SSL for dummies
  • Stylesheet basics

Monday, July 09, 2007

SSL For Dummies

Some time back I interviewed with Amazon.com for a developer position at their local Cape Town office here in South Africa. Unfortunately, after surviving the first harrowing telephonic interview, I then proceeded to bomb gloriously in the second interview, conducted by a guy called Quinton. I have to say, despite my short circuit, this was the toughest interview process I've ever been through - which bodes well for the quality of people hired by Amazon.

While I'm not sure how well I fared on the initial part of the second interview, I do know that I completely fell apart when Quinton asked me to explain SSL to him, as I would if I were explaining it to my grandmother. Now that's an excellent question. It tests how well you know SSL, and it tests your communication skills - most notably your ability to relate difficult concepts to others. I knew what SSL was and how it worked, but I guess in the heat of the moment, I wasn't expecting the whole 'splain it to ya grandma' angle, and I folded like a bad hand of poker.

So, the question remains, how would I explain SSL to my grandmother (ignoring of course the challenging aspect that both my grandmothers have passed on)? Okay, well here's my second attempt. Quinton, you listening?

Grandma, I want to explain something called SSL to you. SSL is an abbreviation for Secure Sockets Layer. Now I know you have absolutely no idea what that is so let me see if I can explain it to you in a way you'll understand.

Let's suppose that you want to send a letter to uncle Ben with some confidential information in it. (That's okay grandma, I don't know about your secrets, you don't need to look so uncomfortable.) As you know, our postal service is not very trustworthy, and they constantly snoop in our mail, and steal valuables like cash notes we send inserted in cards. So how do we ensure that your letter arrives at uncle Paul intact, and untouched? Well here's how we do it.

You will have a special box, that can only be locked with a key that only you have. That box can only be unlocked with a key that only uncle Ben has.

Friday, July 06, 2007

Format this!

If, like me, you've got a free Blogspot blog, and you've wrestled with your blog posts, painstakingly adding spaces throughout your sample source code, only to see them cruelly removed and reformatted by Blogspot, then here's a useful on-line resource to use to keep you from falling into the pit of insanity.

http://formatmysourcecode.blogspot.com/

It'll take your source code for you, convert it to HTML that renders in a neat little dotted margin box.

Here's a sample of arbitrary source code. Here's what it looks like without any assistance - I simply took some code, copied it, and pasted it in. Bear in mind, it was correctly formatted initially:

/**
* The HelloWorldApp class implements an application that
* simply prints "Hello World!" and some other stuff to
* standard output.
*/
public class HelloWorldApp {

/**
* Creates a new instance of HelloWorldApp
*/
public HelloWorldApp() {
}

/**
* The main entry point.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello World!");
for (int i = 0; i < 10; i++) {
switch (i) {
case 0:
System.out.println("Starting");
break;
case 9:
System.out.println("Ending");
break;
}
System.out.println("Looping " + (i + 1));
}
System.out.println("Goodbye World!");
}
}

Yick! What a mess. Clearly you can see that's not what we're after. The indentation has gone, the line breaks are gone and if you stare too long, your eyes may bleed.

So, a quick Google search and we discover that putting a "pre" block around your source code will preserve its formatting thusly:

/**
* The HelloWorldApp class implements an application that
* simply prints "Hello World!" and some other stuff to
* standard output.
*/
public class HelloWorldApp {

/**
* Creates a new instance of HelloWorldApp
*/
public HelloWorldApp() {
}

/**
* The main entry point.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("This is a really long string that will probably not show the entire line since it is really long.");
for (int i = 0; i < 10; i++) {
switch (i) {
case 0:
System.out.println("Starting");
break;
case 9:
System.out.println("Ending");
break;
}
System.out.println("Looping " + (i + 1));
}
System.out.println("Goodbye World!");
}
}


But it still isn't quite there yet is it? In my case, my blog template snips off the end of long lines as per the second line printed above.
So, FormatMySourceCode to the rescue. I pasted the above code into the top text area, hit the "Format Text" button, and the copied the resultant HTML in here:

/**
* The HelloWorldApp class implements an application that
* simply prints "Hello World!" and some other stuff to
* standard output.
*/
public class HelloWorldApp {

/**
* Creates a new instance of HelloWorldApp
*/
public HelloWorldApp() {
}

/**
* The main entry point.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("This is a really long string that will probably not show the entire line since it is really long.");
for (int i = 0; i < 10; i++) {
switch (i) {
case 0:
System.out.println("Starting");
break;
case 9:
System.out.println("Ending");
break;
}
System.out.println("Looping " + (i + 1));
}
System.out.println("Goodbye World!");
}
}


Now that looks a lot better don't you think? And it has a nifty scrolling feature for any long lines.

It's still not ideal. It'd be nice if the Blogspot website had support for stuff like this built-in, so you didn't have to go to the "Edit Html" tab.
But it's better than nothing.

Tuesday, July 03, 2007

Crossing JACOB's Java COM bridge

We've used the JACOB Java COM bridge recently to overcome a few hurdles with our Exchange mailbox backup plug-in for our main product, Backup Professional, here at Attix5. And I have to send out thanks to the guys who are responsible for developing this very capable utility library.

Microsoft do not recommend backing up individual mailboxes. The reason for this is that currently there is no protocol that can do this efficiently, and Microsoft do not plan to provide one, as they feel the full Exchange backup, plus prudent mailbox management eliminates the need to backup individual mailboxes. While they do provide a utility, Exmerge, to export mailboxes to PST files, this is intended as an administration tool. But hey, people will take the path of least resistance, and as such Exmerge is used to do single mailbox backups.

The problem with Exmerge (and as far as I know, all products that do single mailbox backups) is that it uses MAPI to accomplish the export. MAPI was never intended to be an efficient high-volume backup protocol. So as a result, backups via MAPI are s..l..o..w. Furthermore, configuring MAPI on a machine generally requires extra DLL's and MAPI profile configuration. What this means for us is that we frequently ran into problems at client installations getting all of this to play nice.

All we actually need to do in our plug-in, is to retrieve a list of mailboxes for the user to select from, for backup. This might not sound like much of a task, but you'd be surprised how MAPI complicates this. For one thing, bare in mind that our client software is a Java codebase, so we have to jump through a JNI hoop to accomplish all of this. Anyway after the changes to Exchange 2000 and up, where the directory store was extended to Active Directory, I realized we could actually just query Active Directory to accomplish the same task.

Cue JACOB and Active Directory scripting.

JACOB, as the name implies, is a bridge between Java and COM. I won't elaborate further in this post, but you can find out all the dirty sordid details here. There are other Java COM bridge products out there, but I found good coverage of JACOB, and I also noticed that my favourite Java IDE, Intellij IDEA, have started using it in their product, so hey, it must be good!

I'm drawing this out a bit now, so let me cut to the chase, as the say. If you download JACOB, you'll find a samples folder, that has a very useful set of classes for use with ADO. That is what I used to do our AD scripting. This turned out to be quite an easy exercise though I did have to do my own mental translation between the ADSI scripts and the ADO class API usage.

Here's a scripting example of how to do a mailbox query:

set oConn = CreateObject("ADODB.Connection")
set oCommand = CreateObject("ADODB.Command")
set oRS = CreateObject("ADODB.Recordset")
oConn.Provider = "ADsDSOObject"
oConn.Open "Ads Provider"
set oCommand.ActiveConnection = oConn 'set the active connection
strQuery= ";(objectClass=person);adspath,name,legacyExchangeDN;subtree"
oCommand.CommandText = strQuery
set oRS = oCommand.Execute 'Execute the query
While not oRS.EOF
vObjectClass=oRS.Fields("objectClass")
// do stuff here
oRS.MoveNext
wend
This is what the Java ADO implementation translates to:

Connection conn = null;
ActiveXComponent ax = null;
try {
conn = new Connection();
conn.setProvider("ADsDSOObject");
conn.Open();
Command command = new Command();
command.setActiveConnection(conn);
command.setCommandType(CommandTypeEnum.adCmdText);
ax = new ActiveXComponent("LDAP://RootDSE");
Variant v = Dispatch.call(ax, "Get", "defaultNamingContext");
String dnc = v.toString();
String ldapStr = ";" + ldapQuery;
command.setCommandText(ldapStr);

Recordset rs = command.execute();
Fields fs = null;
try {
fs = rs.getFields();
int columns = fs.getCount();

if (rs.getEOF()) {
return list;
}

rs.MoveFirst();
String[] row;
while (!rs.getEOF()) {
row = new String[columns];
for (int i = 0; i <>fs.getCount();
i++){
Field f = fs.getItem(i);
try {
row[i] = f.getValue().toString();
} finally {
JacobUtils.safeRelease(f);
}
}
list.add(row);
rs.MoveNext();
}
} finally {
JacobUtils.safeRelease(fs);
JacobUtils.safeRelease(rs);
}
} finally {
JacobUtils.safeRelease(ax);
JacobUtils.close(conn);
JacobUtils.safeRelease(conn);
}
Quite a mouthful eh? (Disclaimer: I've ripped most of this out of my code and simplified it some for simplicity, so if you copy and paste and it doesn't compile, don't blame me. I promise you it all compiles on my side.)

The problem with this code is that if you run that query, expecting to get all (say) 2091 mailboxes in your AD forest, you'll be surprised that you'll only get 1000. That's what happened to us, but we didn't realize this until we had deployed into a live site at a client site, and had the client complaining they couldn't see all the mailboxes in certain OU's. Man, talk about a hair-pulling exercise. Yes, I know, those of you seasoned AD LDAP'ers will be going "Well d'ugh!", but you see I wasn't and still am not a seasoned AD LDAP'er.

So after running a test script on the production server, we noticed the 1000 row limit returned by the query. This was a peculiar limit. I doubted that there were exactly 1000 AD mailboxes, though I did for a moment wonder whether they had a "1000 user Exchange license". I said just for a moment, so stop laughing. Nevertheless, a Google search quickly revealed that this was actually an Active Directory search issue. Active Directory has a MaxPageSize setting, that limits any queries to 1000 rows, unless you enable paging. Google again to the rescue, and I determined that to enable paging, you simply do the following:

oCommand.Properties("Page size") = 99

This simple line tells AD to retrieve ALL possible rows. AD handles the actual paging in the background. That's it! That's the fix. Now, this sounds simple, but alas it didn't turn out to be so simple on the Java API side. I tried numerous things, using the Dispatch.get(), Dispatch.call() and Dispatch.invoke() methods of JACOB with all sorts of permutations targeting the command, or doing a command.getProperties() and setting "Page size" on that, but all attempts got me a JacobException. At the edge of my sanity, at the point where I was about to give up programming for a career sweeping the streets, I had an epiphany. Actually, I had the foresight to open Visual Studio and have a look at the API docs for the Properties returned by ADODB.Command.Properties. To my surprise, it was a read-only Properties class. What gives? Well that gave me the clue that all required properties were already there in the Command, and that I simply needed to find that property and set its value appropriately. So to cut a long story short, I came up with this:


Properties props = command.getProperties();
try {
for (int propI = 0; propI <> props.size(); propI) {
Property property = props.getItem(propI);
try {
String name = property.getName();
String value = property.getValue().toString();
if (name.equalsIgnoreCase("Page size")) {
property.setValue(new Variant(1000));
value = property.getValue().toString();
}
} finally {
JacobUtils.safeRelease(property);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JacobUtils.safeRelease(props);
}
I inserted that block just after I set the command text, and just before I execute() the command, and hey presto! It all worked like a charm. If on the 4 July, you heard an exuberant, huge shout of elation and wondered who that was, it was me. Sorry.

Wednesday, March 14, 2007

"Griffin, great and growing"

That is (or was) the wording on the water tower for the humble town of Griffin, GA, U.S. of A. I once had a colleague who lived there, and he mentioned that quote with a wry smile. I almost want to say "Grails, great and growing." I've been playing around with Grails now for a few weeks. Unfortunately due to my work commitments, I tend to have sporadic spurts of play, but I'm getting more and more used to it with each session.

Clearly a lot of work has gone into Grails. Chatting on-line to Graeme Rocher, the Grails project lead, I learned that he has an hour to kill on the train from Brighton to London and back - that's an hour there, and an hour back - hence he has time to work on Grails. Time well spent by the looks of it. At v0.4.2. Grails is already quite complete in terms of the architecture and the basic components that you need in a web development framework. What I like most about Grails is that underneath, you're running Java, and Grails uses proven Java libraries like Spring, Hibernate, and Sitemesh. The fact that you mix in a bit of Groovy to glue it all together is a wonderful compromise between productivity and scalability.

I think that's what bothered me about Ruby on Rails. Productivity is great, but at the end of the day, you're still running Ruby, and underneath it all, it's Ruby, and the web server that you use for Rails is essentially single-threaded. Now, before this starts a flame war, I have read about how Rails developers accommodate this to accomplish scalability, so I have to take their word for it that it accomplishes their desired levels of performance. However, to a hardened Java developer like myself, the fact that you're effectively running Java when you're running Grails is a distinct benefit. If I haven't said it eloquently enough, I think Graeme Rocher himself said it best in this entry on his blog.


I think I liked the following quote from that entry best:
Dynamic languages are only useful for small to medium complex applications. This is also "fact". Having supported a multi-tier Perl system for a number of years I would rather die than have to write a complex banking system completely in Groovy or Ruby. But, I would be quite happy to write parts of it in either. If you take this approach you get what I call scalable complexity. The ability to start off in a dynamic language and when things get tricky implement certain parts in Java.
That hits the nail on the head in terms of what I was trying to explain earlier. "Scalable complexity" - Graeme, hope you don't mind if I use that in a meeting somewhere to build up my Dilbert points. ;-)

What's interesting in this debate is the clear sides forming within Javaland on the merits of adding effort to Groovy or of shoehorning JRuby into the mix instead. Personally, there's no debate. As Graeme points out, if you read that entire entry, if you're dealing with Groovy, you're dealing with Java. If you're dealing with JRuby, you're dealing with Ruby, with it's own of (different) threading model, I/O, API etc. So you're going to have to be familiar with both Java and Ruby. With Groovy, you're only dealing with Java. Considering Groovy is equally effective and productive, it is hard to understand why Sun are trying so hard to undermine their own language.

As I've indicated previously I've long felt Java technology suffers from really bad marketing. Often the concepts are great, but the name alone prevents you from daring to put a book about it on your shelf, for fear of being shunned like the lepers of old. No offense, but Groovy is a really horrible name for a technology that wants to be taken seriously. Perhaps that's something that the Groovy stakeholders should consider changing. Perhaps that's why Sun are too scared to strap themselves to that wagon. Of course, I don't really consider myself a marketing type, so I won't attempt to offer an alternative. I do know names like "C#", "C++", "Perl" and "Delphi", for instance, can be talked about without the need for copious blushing, or girly snickering under the table at each mention of the name. What's in a name? Maybe more than we really think. What do you think?

Thursday, March 01, 2007

Choice is good, too much choice is bewildering

Ever been to a restaurant that has a 30 page menu, and you have one hell of a job trying to decide what to eat? I have. It's very bewildering. I like choice. Give me a choice between fillet, rump and sirloin, and I'm okay with that. But give me a list of 40 pizzas and I have a dizzy spell.

Now take that a step further, where you find a restaurant that you're really impressed with. You had their Chateau Briand and loved it the last time you were there. You walk in with your mates, sit down, and look for the Chateau Briand on their menu, and it's not there. So you ask the waiter:
"Erm, what happened to your Chateau Briand?"

Waiter: "Oh we don't offer that anymore, but now we have this really scrumptuous Carpet Bagger steak!"

You: "But I really liked the Chateau Briand, what was wrong with it?"

Waiter: "Oh nothing but the chef got tired of making that. He felt it was becoming passé and wasn't sexy enough anymore, so he stopped preparing that. But he's now really plugging his CarpetBagger steak!"
This morning I had a 'debate' online with a mate of mine, Chris Miller. He's an annoyingly smart developer who more often than not wins these little debates we have. I posit, he counter-posits, I counter-counter posit, and he slam-dunk posits, and then I end up sobbing in the corner. Okay, I digress. The point is I was bitching and moaning about the constantly changing landscape that is Java Web Frameworks. The huge proliferation of Yet Another Web Framework's that is out there in the Java web space. I haven't done Java web development for quite some time now, and recently have returned to the web space because of a personal project I want to explore. I refer you to my recent posts while hitching a ride on the Grails bandwagon.

The last time I did a Java web application, I chose Webwork v1.x as my preferred Java web framework. Webwork was a great framework. A very unimposing, yet powerful framework, true to the intelligence that is Rickard Öberg, the initial developer of Webwork, before it entered the OpenSymphony suite of frameworks. I enjoyed developing with Webwork as it allowed me to focus on the business features I was trying to implement without imposing any configuration distraction, or "square-peg-in-round-hole" forcing. There were a number of really smart individuals who had a hand in Webwork development, like Mike Cannon-Brookes, Hani Suleiman and Joseph Ottinger.

Then one day, a guy by the name of Patrick Lightbody had some or other epiphany and decided that Webwork needed a complete rewrite, basically, and he started on a journey that became Webwork 2. Development on Webwork 1 ceased. Hani made a valiant effort to try to migrate some new (and admittedly useful) functionality from Webwork 2, back to Webwork 1, but he had to work to pay for all that Mac machinery he owns, and so Webwork 1.x development basically ground to a halt. A year or two later and what do we have again? Oh look, Webwork 2 and Struts are merging to become Struts 2. Imagine my surprise. Why? What was wrong with Webwork 2? It's almost like these guys just get bored and decide to rewrite stuff.

Chris (Miller) argued with me that this was irrelevant. That there was nothing wrong with Webwork 1.x that should have caused me to have to upgrade to Webwork 2, other than if I was simply trying to remain 'trendy'. Now as somebody who doesn't get out much, 'trendy' isn't a moniker I would use for myself, and it's not something I attempt to accomplish. However, as I indicated, there were features which Webwork 2 had, which would have been useful in Webwork 1. Off the top of my head, I offered 'interceptors' to Chris, as an example. So you either stick with Webwork 1 and look enviously at all those using a better way to do what you're doing, or you upgrade (probably yet again!) or you enhance Webwork 1 yourself (which I'm not sure if I'm smart enough to do, and I don't have the time). Chris contended that despite the noise that exists in the Java landscape, it's usually easy enough to sift out the wheat from the chaff and if you just focus on the small handful of wheat, you can stick with one choice for a long time before you might have any need to do the upgrade dance. This is true, though often the most-used framework is not always the best framework. Struts 1.x is testament to that.

I guess for me, the issue is the sense that there are so many smart developers out there, giving of their intelligence and time, that it's a pity there isn't more cohesion amongst them. Is it ego's that clash? Disagreements that lead to feuds which lead to divergent frameworks? It seems like there's so much time wasted because of differences of opinion, that lead to reinventions of the wheel. These reinventions mean the rest of us who use these frameworks do a lot of tail-chasing.

I guess beggars can't be choosers, and if I'm not going to contribute in some meaningful way to these frameworks, then I can't complain. Put up or shut up. True, I can't argue with that. But from an objective perspective, it's still a pity. Take for example the Java workflow space. Here's a post from Carlos Perez's Manageability blog. Just look at that proliferation! I count 40, yes, 40, different Java workflow frameworks. I mean, surely there's enough commonality in the workflow space that we don't need 40 frameworks. Is it bad co-ordination? Poor communication? What is it?

Well I don't really know, but it's annoying, and it's a pity. And furthermore there's really precious little you can do about it. Open source is a voluntary beast, so you can hardly go around dictating to developers as to what they should do with their spare time.

If you've read any of my earlier posts you will have seen that I've jumped onto the Grails bandwagon. I just really hope and pray that Grails sustains the attention of the developer community sufficiently to remain relevant for a long long time. If not, it'll be a bit of a gamble since Grails applications, by their very nature, are significantly different to most other Java web frameworks, and web development methodologies.

Postscript: The one fairly important aspect I've completely omitted here is what we get from those who are somewhat at the reins in our industry. Consider, for example, Java Server Faces (JSF). I must admit to not having played with JSF at all. However, I can't say I've found a single positive comment on JSF by those not specifically biased due to their involvement in the JSF effort. The overwhelming consensus that I have picked up on is that people feel that JSF ignores what Java developers actually asked for. That it's delivery was grossly impotent when considering its potential and initial promise. EJB is another example. Look at EJB 1.x and 2.x. Yick! EJB3 seems to finally be getting somewhere close to what Java developers have wanted all along. So does this suggest part of the problem: that the leaders in the Java space are too introspective, and they don't actually listen to what their developer masses are asking for? How long did developers complain about the lack of exclusion patterns in the servlet specification? So perhaps our fearless leaders have some blame to bear in this mess that is the Java web framework landscape.

Wednesday, February 28, 2007

The End of the Tunnel

Ok, so I've finished the book. And first off, I should say that I think Jason Rudolph is a very good author in communicating Grails to the newbie. He really has a skill in taking you organically into the subject matter, and his writing style is relaxed and 'easy on the eyes'. Nice one Jason!

So I finished my last post as I was about to head into authentication. Again, I was impressed with how easy it was to add 'security' to my application, at the method level. It was a closure at the top of my controller class, and I was done. Very slick. I do recall this is how Rails works as well, so wasn't completely taken by surprise.

The rest of the book went into tweaking the UI with improved layout, which uses Sitemesh. For those not familiar with Sitemesh, it was created by the very capable Joe Walnes, and was part of the OpenSymphony suite of frameworks, along with other capable frameworks like WebWork, and OSCache. I've used Sitemesh on former web application projects and it was very capable. Grails uses Sitemesh under the covers but you don't actually realize it until you see the Sitemesh configuration file in the WEB-INF folder - though you don't actually have to edit the file at all. It's just, there. There's also some coverage of CSS tweakage, but that was fairly standard and as expected.

Grails has built-in support for testing, just like Rails. It generates placeholder test classes for you to embellish. I won't testify to being an uber-unit-tester, but it's there, and should I develop the discipline further, it'll be handy. Testing your application, once you've filled out the tests, is as simple as 'grails test-app'.

Grails has built-in support for logging using log4j. From what I can tell it logs error messages by default. I'm not sure if you can use other levels, like INFO or WARN, but there must be a way. The author didn't indicate what that way was though. I'll have to look into that. Nevertheless, there are separate log4j.properties files for development, test and production, which is again slick. It's never pleasant leaving a logging level at DEBUG on a production deployed application.

Lastly there's the deployment of your application. A very nice touch is that 'grails war' will package your app for you in your chosen environment (dev, test, prod), with all the targeted settings, into a neat deployable WAR. 'Production' is the default but you can type 'grails dev war' for instance, and you'll get a development WAR with your development settings.

So, what conclusions do I have? Well I certainly am very impressed with how 'complete' grails is. At v0.4 I almost expected to see lots of "To be done" comments and sections, but really it's quite mature for such a young project. I've done some reading in blogs and such, and there are doubts cast about its maturity and readiness for enterprise deployment, but it's clear from the core developers intent that enterprise is their target. I certainly can see how Grails will be a productive framework to develop with. And I do plan to use it on a greenfield project I'm about to embark on. It's a personal project, but one aimed for an enterprise environment. So we'll see how it goes. I'm still ignorant as to how Grails works once deployed. Are those Groovy scripts reinterpreted on every request/response, or are they compiled to bytecode on the first execution and reused from there. I don't much fancy a 'reinterpret' design to a web application that I'd like to scale to high load. But these things can be subjective, and the proof of the pudding is in the eating.

Pudding anyone?

The Angels Sang

The angels sang, no doubt about it. And it wasn't just a benign little "Aaaaah", it was like a full Mormon Tabernacle Choir sonate.

Man, I can't believe how impressed I am with Grails. Where on earth do these Grails developers find the time to implement all this stuff, for free?! Since my last post I've been tweaking the basic auto-generated scaffolding and code that Grails produces by itself. I've tidied up some error messages, which in itself was impressive in how Grails scaffolding builds validation and error notification automatically into form submission. Validation with the 'constraints' static object is very easy. Customising your error messages follows a class.action.constraint format, also - dead easy. You edit or add to a single messages.properties file and that's it.

And here it's worth mentioning the 'flash' context, which is something I'm not aware of in other Java web frameworks, but is also something borrowed from Rails. In Java you typically have page, request, session and application context. For short-lived objects, you usually place them in page or request context. Session is more long-lived, and application obviously is the longest lived in terms of web application object lifespan. Flash context slots in somewhere around page and request, in that while page and request contexts 'die' after a response has been made to the user, flash context lives until the next request. So it lives sort of from 'response - next request' and then Grails cleans it out. Why this is useful is because often, after you've completed a use case, you want to redirect your user to a different URL, not just simply forward them. With page and request context, anything you place in those contexts will be gone when the redirect request comes back. With flash however, objects placed in 'flash' context live until the redirect request is completed. I recall from past web applications, where something like that would have been useful. Giving a confirmation message with a redirect, for instance, is very useful. I can't recall off-hand but most likely I placed stuff like that in the session context and nuked it after the next request was done, which is probably similar to how it works in Grails, but I didn't have a formal concept for it; more like a stab in the dark.

Anyway, moving along. Adding taglibs is also very easy, and has a special place in a Grails application. The conciseness of Grails - or actually - Groovy code, is very convenient here too. I followed the book and created formatting taglibs to format my numeric, date and currency fields, and all within a minute or two. Of course, I was surprised that these tags weren't already in the core Grails taglibs, but hey, it's only v0.4 at the moment, so, baby steps.
This also bears mention of the GString (*snicker*) class which allows for transformation within a String. That probably doesn't make much sense, so allow me to copy and paste from the official Grails API docs:
Represents a String which contains embedded values such as "hello there ${user} how are you?" which can be evaluated lazily. Advanced users can iterate over the text and values to perform special processing, such as for performing SQL operations, the values can be substituted for ? and the actual value objects can be bound to a JDBC statement.
Can't deny some of that strikes fear into me - I mean linking a String to JDBC SQL operations just screams 'security hole', but I probably don't fully understand that definition. I'll be sure to investigate this more in the days to come. But it does mean you can do things like the transformation indicated in that definition, and determine the final value in real time.

Now, one thing that blew me away was how easy it was to setup search capabilities, using default search syntax for simple searches, but also integrating very intuitively with Hibernate's Criteria building. Here again, no XML files to configure, just fairly straight-forward, simple code and naming conventions.

The similarities of Grails to Rails are very obvious, and one can see the Grails developers have done a good job with this. I find myself understanding this book very quickly simply because of my understanding of Rails. Those of you who haven't ever read up on Rails may find some concepts confusing at first. So take my word for it, they are good ideas. Each controller action is defined by a closure, and convention over configuration means you don't have to tweak 2 or 3 XML files to add an action to your controller. View resolution is determined by your controller and action, and the brevity with which you can accomplish much is also a Rails testament.

Now if you're anything like me, you're probably thinking "Ok, all of this is cool, but honestly, this is not complex stuff, and all this proves is that Grails accomplishes simple goals, simply." True, very true, which is why it's reassuring to see that one of the headings of the next chapter, "Not Just For Intranet Apps", is "Beyond CRUD". This is where I add authentication to my application, with specific permissions to specific views etc. Stay tuned as I delve into the unknown.

Tuesday, February 27, 2007

The Race Continues

So this is day 2 (I think) of my Grails journey and so far I'm really impressed. Everything has gone as advertised and the angels are going to sing any day now.

Yesterday I started on Jason Rudolph's very excellent free eBook called "Getting Started With Grails", which basically gives a primer on Grails using a Running Club registration application as the basis. His coverage is very well done, and explains each concept (so far) in just enough detail to keep the pace interesting. I'm on page 44 of 133 already and believe it or not, when I started, I can honestly say I had a simple Race Registration web application up and running within 2 minutes. Hard to believe. And Grails is extremely similar to Rails, which I'm thrilled about, since I do think Rails is onto something with their development approach. As with Rails, so much adheres to convention over configuration.

One thing I haven't found yet with Grails is whether it has any schema migration support as per Rails. Since I haven't seen any such headings I'm guessing the answer is 'no'. I'll have to find out from the Grails evangelists what their response to that is. I found that the Rails migration support was very useful, and followed my strategy in C# and Java applications I'd written that had a 'moving target' schema. I had a SchemaMigrater utility that would apply the latest SQL scripts depending on version numbers in the code. It works really well. Anyway, I've made a mental note of that and will follow up later.

The step I'm at currently is to replace all implicit scaffolding with the explicitly generated scaffolding, which is something you can do with Rails. Jason has basically led me through the basic setup, relationship definitions and domain validation steps. Currently I have a default CRUD application that links Races to Registrations, and it does basic validation on the Race and Registration inputs. Next, apparently, we're going to tweak the default layouts etc.

Oh one other note. Grails uses Hibernate, Spring and Sitemesh under the covers. What's impressive is that so far I've not touched a single Hibernate, Spring or Sitemesh configuration file. Everything thus far has been convention over configuration. Impressive. I'm kinda excited to click the 'Next Page' button in Acrobat. Tweakage, here we come.

Monday, February 26, 2007

Grails Kick - er, Quick Start

Well I'll be. I've just completed the Grails Quick Start and I must say, I almost heard the angels. They weren't singing yet but I think I heard them warming up their voices.

The Grails Quick Start is fairly intuitive to follow. Just do what the instructions suggest and you should be fine. I won't run you through it blow by blow because it's online for your own viewing convenience at: http://grails.codehaus.org/Quick+Start, but this is a précised summary of what I did.

I ran a script to create the project outline. That worked as advertised. At this juncture the Quick Start points out that you can change the data source for your brand spanking new web application if you so desire. Or it'll start with an in-memory HypersonicSQL DB for your convenience so you can get up and running immediately. I'm good with the HSQL DB for now. I'm just having fun right now anyway.

Following this you create a domain (or model) class, using a Grails script. The Quick Start offers a 'Book' domain class with a 'title' and 'author'. Just do that. Then in a Groovy bootstrap script you setup some test data. Easy-peasy. Done.

Lastly, like any well-behaved MVC prodigy, you need to create a controller for your model. Again, call your controller 'Book', and Grails will create a 'BookController' for you. Schweet. That worked too! So far so good.

(Quick aside: the Quick Start indicates you can do a 'grails generate-all' and give that the 'Book' name and it'll create your model and your controller, but I did each step on its own. Now that I think of it, I had to do a 'grails help' to figure out that they do a 'grails create-controller' because the Quick Start doesn't indicate that, but I'm sure generate-all will accomplish the same thing at the end of the day.)

Now of course you need to have view stuff, but like Rails, Grails offers the concept of 'scaffolding' which provides the basic structure for CRUD (CreateReadUpdateDelete) operations on your brand spanking new domain/model class. So a quick edit of my BookController to tell it to scaffold the Book model class, and I'm ready to rock and roll.

The rock and roll part is as sexy and as simple as typing 'grails run-app' from my project root folder. Baddabing! My web application launches. I haven't yet looked at what Grails uses but it's obviously a lean instance of Tomcat or Resin or some such. That's irrelevant to me at this time, since I'm itching to find out whether my browser can make sense of: http://localhost:8080/myproject/book/list.

I type in the URL, hit Enter and wait with pregnant anticipation.

Whooooot! It works!

I am impressed. Like I said earlier, I'm sure I heard the angels doing voice warm-ups. I get a list of the books I typed into the bootstrap thingy, and I can add books, delete books, or go to a home page for my web application that indicates which controllers exist in my web application. And I didn't type a single line of view 'stuff'. This is neat! It took me all of about 2 mins to get a Java web application up and running. I'll be done with my new project in about 4 hours. Okay, okay, I'm getting ahead of myself. But so far so good, which is not often the case when I play with open source (i.e. open sores) stuff.

My curiosity now wants to know how Grails will cope with changes to my domain, controllers and views. That's still a bit of an unknown. Onwards we march.

Grails - The Journey Begins

Grails has a fairly neat and intuitive home page. You can find the most important stuff there like, er, well, documentation. Imagine that! Along with an 'Installation' page, and a 'Quick Start' page, there's also a 'User Guide', 'Tutorials' and 'FAQ'.

There's 'Reference' links as well as the obligatory mailing lists, wiki, issue tracker and SVN pointers.

The content of the main page bares some testimonials including one that says:
"I found Grails and it was like the heavens opening and angels singing "AAAAaaaaawh". - Les Hazlewood

Wow, that's quite a testimonial. So far I haven't heard the angels, but I'll let you all know, the moment I do.

Nevertheless, while listening out for the angels, I followed the instructions from the Installation page and all went according to plan. Installed Grails, set some necessary environment variables and typed 'grails' in expectation of a help screen and guess what happened... it worked! Pleasantly surprised by this, since a lot of open source projects I've tried DON'T work 'out of the box'.

One point to note is that from previous sandbox activity on my part, I already have Groovy installed on my machine, so I wonder if that installation would have still worked if Groovy wasn't installed. *shrug* I'm not going to investigate that further. I'll leave that as an exercise for the reader. *grin*

In Search Of The Holy 'Grails'

Are you like me and you develop in Java but you keep encountering this constant raving about this Ruby On Rails phenomenon that keeps getting so much bandwidth in the online rags? Not? Well okay, but that's been my experience, so sit there and pay attention anyway. It'll be interesting, I hope.

In preparing to develop a greenfield web application recently I decided to get my hands dirty with this holy grail known as Ruby On Rails. I have to say I was very impressed with it. From the outset I was constantly thinking "Hmm, well that's quite clever, I wish Java web development was more like that." Honest, over and over again. From how it creates this complete project skeleton, to how the scripts generate all this stuff for you, to their philosophies of Don't Repeat Yourself (DRY) and Convention over Configuration. And I thought to myself: "Self, this Ruby On Rails thing isn't new anymore, and you haven't done Java web development for a while, so why not see if there's anything that's been done in the Java web world to address this approach that Ruby on Rails has taken?" So I went to look for something holistic in its approach, like Rails, but that leverages the wealth of Java technology that already exists.

At first I didn't find anything that was obvious from the usual headlines on The Server Side, or on InfoQ or on OnJava, or Javaworld and so on and so forth. The usual suspects of Struts 2 , Tapestry and Spring's WebMVC grabbed most of the headlines, and I was trying to get away from their XML configuration conflagration (sorry, that was a mouthful). I did encounter a web framework called Stripes, which seemed to make a reasonable effort, but that still wasn't quite what I felt I was looking for. Then by chance I came across Grails.

As the name implies, it borrows heavily from the philosophies of Rails and at last I'd found something that 'seemed' to do what I felt a Java approach could do, if it mimicked Rails. Like Rails, Grails uses Groovy just like Rails uses Ruby. Groovy is, for all intent and purpose, a Java scripting language. Grails uses Groovy to empower itself and accomplish various tasks with a minimal set of lines. Grails was initiated by Guillaume LaForge and founded by Steven Devijver and Graeme Rocher - who is the current Project Lead. It's still fairly young but I've communicated with an Australian, Glen Smith, who is using v0.4 in production projects. As a South African, trusting an Australian defies common sense, but hey, us Southern Hemispherians have to stick together.

So I thought I'd try out Grails and log my experience here. If you just kick the tyres it won't reveal much about the vehicle. You need to take it for a test drive, and not just amble up and down the road.

So seatbelts on, here we go.

Tuesday, February 20, 2007

I love coffee but I hate Java beans

If you've done any Java development, you'll have encountered the all-too-popular-but-oh-so-lame naming convention of using the word 'bean' in your class names. It's everywhere in Java technology, you get ActionBeans, you get JavaBeans, you get Enterprise JavaBeans, and then you get "Netbeans". I can't stand it. If there's anything I can't stand about 'open source'-ish technology it's the often lame naming conventions that you find. Word to the wise, Gnu is NOT a cool name to prefix everything with. You feel like somebody with a speech impediment every time you refer to something under the Gnu 'brand'. Then you get the daft Unix/Linux naming stuff of xEdit, or kEdit or whatever. All these terms are symptomatic of developer types also doing the 'marketing' of the product since it's 'open source'.

For some reason, while Java was rooted in the commercial company known as Sun Microsystems, it seems the developer types there should have gotten some help from the marketing department when they gave names to their technologies. Who was the dolt who thought "Well Java has to do with coffee and you get coffee beans, so I know, let's use the word 'bean' everywhere we can to describe stuff." And all the other geeks around him started snorting and snickering in childlike glee at the brilliance of his epiphany. Notice I said 'his', since I am convinced a woman would have been way more original.

I wish I had a Men In Black magic pen, and could flash that red light from a website somewhere that would make everybody just forget about the word 'bean' in any other context than a coffee shop or a food source that encourages flatulence. It's lame, and it should go! I feel like a kid in a playschool sandpit everytime I have to type the word 'bean' anywhere in my code or in documentation. What's next? Do we extend the idea to other aspects of our code. In future instead of having:
private Person person;
I'll make it:
private Person personWerson;
Instead of:
private ShoppingCart cart;
I'll make it:
private ShoppingCart trolleyWolley;
You get the point. It's all just dumb, and poorly envisioned. Why does an ActionBean have to be an ActionBean. Just call it an Action. Isn't that enough? If you must add something else, call it an ActionComponent, or ActionController, or something more grown up for goodness sake, but whatever we do, let's stop calling stuff 'beans'!

Thanks, I feel better now.