Cache Me Not

Today I worked on an interesting bug that required us to forcefully push out a new copy of a file to any client that connected to our web application. The file was a javascript file containing several functions which are used by our application, one of which was modified and is now used as a trigger for an important part of the application (don’t ask why). Clients to our application are the general public, so forcefully clearing caches was certainly not an option, but our solution might have been made easier if we were allowed to change the name of the file, or even the name of the function. Unfortunately other existing technical requirements did not permit this.

A quick google-later gave me enough evidence that header tags like <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> (for HTTP 1.0), <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"> (for HTTP 1.1), and <META HTTP-EQUIV="EXPIRES" CONTENT="0"> would not be enough to trigger a refresh of the client’s versions. Some sites described that writing out values in the HTTP-Headers might also work, but I wanted to avoid it for not being a very simple solution.

In the end, the solution we deemed acceptable was to simply add a query string to the end of the file so that clients would be tricked into thinking that it was a new file, turning something like: <script src="/scriptForRefresh.js" type="text/javascript"/> into: <script src="/scriptForRefresh.js?forceMeTo=refresh" type="text/javascript"/>

Maintenance Programming’s Da Bomb

I was in a situation this week, where I have been fixing bugs in one particular part of our system for total of two weeks. This situation was created by too many reasons to really list (or perhaps warrants its own separate entry) and is a relatively unusual circumstance for our project since a maximum of two days is all we tend to need for each iteration. Being immersed in ‘maintenance mode’ for so long has really highlighted the different set of skills you tend to draw upon in contrast to our normal operating mode. It has also brought to my attention a few issues that can really help or hinder you when working in this mode. Here’s a few of them:

  • Good logging statements (being careful not to damage the readability of code) that detail the complex state of a system in a readable is definitely helpful as you don’t need to add them yourself or to your debugger.
  • Fast unit tests help to give early feedback when making changes to the system and a change breaks its contract with other components.
  • Fast integration tests gives you the confidence that your system will continue to operate as it has in your production environment.
  • Identifying a bug in business requirements before code is written is definitely cheaper than fixing it later on.
  • Poor exception handling can mask the original source of error. For example, on a previous project, I remember the overly complex exception handling architecture triggered a NullPointerException when handling a simple business exception.
  • Code smells tend to become even more offensive as you wade through its source, which at least helps to identify areas that are good candidates for heavy refactoring or redesign).
  • Repeatable test scenarios for a reported bug which are then translated into code are important against protecting against regressions.
  • Though I agree with the whole philosophy of self-documenting code, I still find comments are important. I find the best ones tend to explain why a block of code was written in a particular way instead of another or the potential side effects changing that may have.

Robust Java by Stephen Stelting

I came across this book when I was trying to compose my next Amazon shipment of books. It caught my eye because I have not read much literature or talked to many people about exception handling best practices. It is certainly a topic that was never taught at University in great depth and something I find tends to be neglected in the workplace.

My initial impressions of the book after reading the foreward and first few chapters is that it is a very well written and a well published book. The author sets the expectations of his readers early with what he is trying to achieve and manages to accomplish his goals in the rest of the book. The format is well laid out and the excellent quality of the editoral work is evident by the ease of reading attained without the interruptions typically caused by poor spell checking or grammatical errors.

Read more “Robust Java by Stephen Stelting”

Adventures In Pair Programming

Pair programming is one of the many Extreme Programming practices that I haven’t been able to use that much on my current project. We have a substitute dubbed ‘pairing’ which attempts to reap the benefits of this practice without incurring its perceived overheads. Part of ‘pairing’ allows us to pair program in certain circumstances (other factors prevent us from doing it actively all the time) and I recently had my first experience (or should that be an epiphany?) to reflect upon.

My first observation during this process was that I found the quality of code I wrote, and even my focus of what I was writing, increased tremendously. I also found myself absorbing more history and appreciation for the code I was adding to, instead of simply getting my tests to pass.

After enjoying my first taste of pair programming, I can conclude that to be really effective at it will definitely take a lot of practice. For example, one of my pair partners commented that I tended to unconsciously ‘huff’ while he was typing (probably because I can type much faster than him or was it because I found myself the victim of the Dominant Pair Syndrome?). Appreciating the feedback (of which I find myself so undersubscribed these days) I started to scour the net trying to look for some resources that described better pair programming etiquette. C2 Wiki has a good collection of resources such as ‘How To Piss Off Your Pair’, Pair Programming Questions, and Pair Programming Doubts. I’ve now added Pair Programming Illuminated to my wish list and am eagerly waiting for a copy of Peer Reviews In Software: A Practical Guide in my next Amazon shipment.

When a Unit Test is not a Unit Test

The term ‘unit test’ was being thrown about today at work but so many things about its context were just plain wrong. Just because our testing framework is called xUnit and each method happens to be called testX doesn�t make it a unit test. People have spent (far too much) time attempting to classify all types of tests coming up with categories like functional, acceptance, integration, or unit-integration tests. In my humble opinion, I tend to think of all tests falling along a spectrum, with unit tests (those that test just enough) on one end and the functional/acceptance tests (those that test too much) on the other.

Each test along this spectrum is important but the speed and quality of these tests will be one of the factors that determine how fast you can change or add to your code base. By all means, slower, bigger tests further along in the spectrum can be substituted for faster, lighter unit tests, but its consequences usually lead to a project that is less agile and more waterfall-driven.

Here are a few signs that your tests may be masquerading as something more than just (better, and faster) unit tests:

  • Your application must be �deployed� to run some of your tests;
  • A user must interpret console output or some other type of result for the test to fail;
  • Each test takes too much time to run (it should be possible to many of these within a second);
  • Excessive amounts of set up are required for each test (a smell that this might be integration test and/or testing too much); and
  • Tests cannot be run without some external resource (such as a database, specific computer or some file);

Generics Misnomer

Why did the latest JDK have to go and copy C# and name their language feature Generics when it looks like this:

List<string> notSoGenericListOfStrings = getInitialListOfStrings();

I hope it’s not just because the implementation happens to lose all of that compile time information, making each strongly typed element the lovely generic java.lang.Object. After reading the reasoning behind its implementation and appreciating some of its motivators, I’m sure it will be all the more be interesting resolving any Reflection or AOP bugs in the future.

Can The Spam

Yesterday morning my blog was flooded with a huge amount of spam (about 40+ in about an hour). I think that the use of any popular blog software (be it WordPress, Movable Type, Blogger) will make you an easy prey for spammers. I know of a couple of people that rolled their own software and haven’t had any spam issues. I have only had one incident of spam since my blog was first made public, but it’s definitely something that I don’t like.

Here’s my list anti-spam initiatives that I intend to take, depending on how bad I feel my spam threshold is being violated:

  1. WordPress Comment Moderation – The latest version (at least available from CVS) includes a comment moderation facility (like MT’s blacklist plugin). This can help you block known aggressors but still requires you to approve/delete each of comment.
  2. Change the name of the page being spammed – As of yesterday, I have renamed the standard wordpress comments page to something else. If this keeps spammers at bay for a while, I’ll be quite happy with that. If they seem to keep up with the changes (am I really worth the effort guys?), I might write a cron script or something to change the name daily.
  3. Change the name of the fields that are posted – Requiring a little more tweaking of the actual code (yay opensource!), I next intend to change the name of the parameters that are submitted, hopefully rendering spammer’s scripts somewhat useless.
  4. Port the security code (SCODE plugin) from MT to WordPress – If it comes down to it, I’m willing to plunge my head straight into PHP just to prevent spam.
  5. Adopt a Bayesian Filter – Brett mentioned this seemed to work quite well on some blogs but requires a bit of training. I hope not to have to get to this point.

I haven’t thought about how I can prevent spams from TrackBack URIs just yet, but I’ll cross that bridge when I come to it. If anyone has any other ideas, I’d love to hear about them, just to add to my arsenal (or should that be my canning factory?).

Update 23 Nov:
After reaching the second threshold in my anti-spam checklist, a simple check of the logs informs me that 176 spam comments have been blocked!

Consequences Of Living On The Edge

We’ve been lucky enough on my current project to move to the latest and greatest Java Software Development Kit (J2SE 1.5). It’s one of those small things that we seem to have a fair (though not total) amount of control over. I think (though I am keen to hear otherwise) that it is the only project in our company who has moved onto this platform in production. I shudder of thinking back to my previous project where we were constrained to Java 1.1.8!

Our team has been developing and testing on the new platform for the last few weeks to ensure that our code remains operational and stable. Here are a few things that we had to do in order to upgrade and you might like to consider if you plan on working with the latest version:

  • Upgrade your IDE – We use the best java IDE as our main development front end. I was previously running an old 3.5 version, and had to upgrade to the newer 4.2 version for support of new language features like Generics. I was glad that we were forced to move only after 4.2 was available because other developers had found many bugs in 4.0.
  • Ensure integration test coverage is high – This project relies on a smaller number of libraries in comparison to my previous project, but our high level of integration tests ensured all of the functions our code exercised worked, or at least we found out what did not. For example, our version of the BeanUtils library didn’t handle some of the things we used it for very well.
  • Test your toolkit – As I mentioned earlier in a previous post, coding style on our project is enforced by a tool called Checkstyle. The latest release does not cope well with the new lexical changes to a Java file so we had to build one based the latest source in their repository (thanks to opensource software!).
  • Exercise new features naturally – Our IDE allows us to configure at what level SDK (1.3, 1.4, 5.0) we would like our syntax to be validated against, and although we were supposed to keep it at 1.4 because the latest version of Checkstyle could still not parse all the new constructs, I accidentally left mine at 5.0. A fellow developer later discovered I had committed some code that exercised Autoboxing without even realising it. Such a nice language improvement (now if only Checkstyle wouldn’t die over the new for-each construct)!

Update Nov 8:

We use YDoc to generate UML diagrams in our javadoc (and to make our Business Analysts happy). YDoc is built with a heavy dependency on JDK1.4.2’s Standard Doclet (that was refactored in the latest JDK). This means that although we can generate standard javadoc, our nice UML diagrams no longer appear. I’ve sent an email to the company (as I have no idea where to find technical support on their site) and now we wait…