Think Distance, Not Speed

Somehow I always seem to end up coding the user stories that have the most demanding time constraints. In a way, I feel flattered that someone trusts my ability to deliver when a critical deadline must be met (and real deadlines are very rare in software, despite what everyone tells you), but it is always interesting to see how people react when a critical deadline must be met.

Over the numerous occasions that I have been working on these “time critical” stories, the common question you are normally asked is, “So when do you think we’re going to be done?” or better yet, “Is it ready yet?” As a developer I find it is better to preempt these sorts of questions by delivering feedback earlier than they expect. Typically this means walking through significant, visible progress with the stakeholder, or bringing visibility to issues that are hindering your ability to deliver (e.g. database environments not available, etc). Customers are typically trained to ask “Is it ready?” because they are given such little feedback. The customer should not be surprised when something will be delivered and it easy to forget this.

Another question that you tend to get asked is, “Can you get it done any faster?” Speed is essential to any business, but it is important to highlight what you sacrifice for speedy delivery. Translated into software terms, this may mean less regression tests to provide automated feedback of features breaking when future changes are made, duplicated code, leading to confusion, additional maintenance and even developer shame, or an undesirable path that meets requirements but leads to an unacceptably sluggish solution as load increases. When time is critical, ideally the business should be prioritising which things are more important, but usually it is left for developers (for better or worse).

Achieving your goals as fast as you possibly can is good, but keep in mind that developers are more like runners than they are computers and do get “tired” (for want of a better term). If you want to run a marathon, you certainly don’t run at the same speed as you would the 100m. Instead of asking how fast you can run, the question that should be first asked is how far do you want to go?

Back to Basics: A Retrospective on Retrospectives

Although I am not the iteration manager for our project, I like try to be our project’s conscience (or at least the conscience of whoever our current iteration manager is). Amongst the (many) things I have been reminding our current iteration manager of is the lack of retrospectives. One reason that agile software processes are better off than traditional long running ones is because feedback is a highly valued principle. Small iterations improve the regularity of this feedback which can then be fed back into the process to help the team stay agile with constant changes in the work environment. Retrospectives (post mortems, iteration reviews, etc) are a great way for the team to put together their views and devise strategies for processes that could be improved for the next iteration. The value of small iterations can diminish greatly if no one spends any reflection time to work out whether not things could be done better (and most things can always be done better).

Sailing is a great visual analogy that highlights the importance of retrospectives. On any sailing voyage it generally takes a while to get to its final destination. The navigator is the person whose responsibility is to keep the ship on course for its destination. They also understand the implications if the ship steers off course and is therefore constantly optimising the journey by considering all the questions that could affect the ship’s ability to get there. Are there enough supplies on board? Is there a storm lying ahead of us? Should we visit the exotic island that’s just a little within reach because our passengers would enjoy it? Even if the original journey is never altered, the navigator is constantly asking and reviewing the answers to these questions.

And just like in sailing, it only takes a little deviation over a long period of time to take a software team far from its original goal without someone (and preferably the team) stepping back and reflecting upon each significant league in the journey. An hour now with the team assuring that you are on track is better than an iteration making up lost ground. Performing reflective exercises more regularly will also improve the quality of the feedback as the team works out what sort of feedback is actually important.

A Closed OpenOffice

Don’t get me wrong. I like the concept of OpenOffice, but just like many other open source projects (not all of them mind you), someone could teach these people about actually meeting user’s needs (and not some idealistic view of simply creating an “open standard”).

Today I had to open a SXW file (an OpenOffice Text Document) on a windows box today and found that nothing currently installed could open it. I didn’t really care too much for the formatting, but I desperately needed the content and opening it up in a notepad-like utility proved fruitless. I was thus forced to download the only “open” office that I could actually view this with (at least that I know of, I could be wrong).

Much to my dismay (not to mention distaste) I was forced to download a whopping 64MB file just to be able to view a 20KB file. I was lucky that I had access to broadband as it would have been super painful over dial-up (oh, yes people still use this!). As a user whose goal was to simply view the raw text in a document, I would have liked to either:

  • Open up the document, ignore what special markup the formatting was in and be able to extract the raw data; or
  • Be able to download the only application that I needed to view the file with.

Useful Oracle Views

Since we finished with our migration to the Oracle 10g database, I have been meaning to post some useful notes about developing in this new environment. This last two weeks, I have found myself using Oracle’s V$ views a fair amount so I thought it might be good to share (or at least archive this information for myself).

What are V$ views?
V$ views are defined by Oracle as dynamic performance related views because they are continually updated to reflect the database state as it is running, and most of the information is pertinent to performance tuning and useful for performance monitoring. You can find more information about V$ views quite easily, both through the Oracle Technology Network or the great AskTom website.

Why should I bother to use V$ views?
Many GUI interfaces are widely available to help administer and monitor Oracle databases and sometimes you may never have a need to use these views. However sometimes those tools are beyond the reach of your normal developer and interfacing with Oracle at this lower level can be the simplest solution for what you need. A database configuration where people who can execute any arbitrary SQL statement should also generally grant them with the access to read from these very informative views.

What are some useful examples for making the most of these views?
Easily monitor through the number of connections with:

SELECT SID, SERIAL#, PADDR, USERNAME, STATUS, MACHINE
FROM V$SESSION

Monitoring the total number of connections as your application is running may give you a good example of how well your application is properly managing its connections. Those connections that sit there in an INACTIVE state are probably ideal candidates for further investigation. If you have the DBA role, you can then kill sessions (with care) with:

alter system kill session 'sid,serial#';

Uncover the SQL statements that are currently running with:

SELECT text.SQL_TEXT
FROM V$SESSION session, V$SQLAREA text
WHERE session.sql_id = text.sql_id

Another view exposes settings for National Language Support (NLS) parameters. We once had issues with database instance managements that resulted in us creating a set of environmental acceptance tests as a cheap way of detecting differences in database configurations. These were useful for ensuring settings such as the NLS_DATE_FORMAT were configured correctly for standard JDBC.

SELECT *
FROM V$NLS_PARAMETERS

A Hole In The Loop

I have been part of a production support team lately and an issue that was raised this week had me concerned about some of the state we seemed to be operating in. We had a situation where a business analyst who wrote the requirements for a particular part of the system had to keep coming back to development asking how that was part of the system was supposed to be working.

I must apologise, but I thought our current process was actually working to ensure that the development loop was tight. Testers would work with BAs to ensure that all the scenarios were covered, developers would write to meet those scenarios and the BA would walkthrough the application to ensure that all of their requirements were met before signoff (completion of the storycards). It could have just been an off-day, but it worries me when business people come to the development team to see what the business rules should be.

Java Net Regressions

Recently we were trying to upgrade to the latest release of Java 5 (the J2SE05_04 version to be exact) so we could make use of the various bug fixes in the VM, and just to stay on the bleeding edge. After running our entire test suite (I could not imagine life without it!), we found that the URLConnection.connect() had a regression, throwing errors when you have a URL containing foreign characters such as éâäàåçêëÇèïîÄèïîÄ (basically anything after %8x through to %FF). Kudos has to be given to Ajit George who did all of the investigation work but does not have a blog to post this on.

For example:

URL foreignURL = new URL("http://java.sun.com/%80/");
URLConnection connection = foreignURL.openConnection();
connection.connect(); // IllegalArgumentException thrown here

We were lucky enough that only our test code exercised this API, but be warned if your application makes use of this and you upgrade to the latest version. A bug report for this can be found here. According to sun, the underlying class that is apparently the problem, sun.net.www.ParseUtil, has had this issue since the latest JDK1.4 version, but this regression appears when you use the URLConnection.connect() only in J2SE05_03 and the current release J2SE05_04 but works fine for J2SE05_02.

Sometimes You Need To Make A Class Less Detestable

A long time ago (well before I was introduced to Test Driven Design [TDD]), I used to think that tests should not really affect the way that the code is written, but I’ve really changed my stance on that. It has got to a point where classes that were not driven by tests stick out like a sore thumb. I was recently working around our ManagementAgent, a singleton that obviously written to work only when deployed into a container (on instantiation, it would require configuration that would only be available from the web.xml file).

I was in a situation where we wanted to add some more configurable attributes to a specific ManagementBean (which the Management agent would add to itself on instantiation) and I seriously saw the need to refactor some of its code. Of course without tests, I knew I could not refactor in safety. I was so revolted by the situation that I was in, that I knew it was time to make the class less detestable.

Since this class was a singleton that only worked when deployed in the container, I knew it it was time its design changed. For starters, my pair and I decided to break its singleton pattern by providing a package protected constructor and an injectable configuration instead of a self-populating one. The introduction of the constructor allowed us to easily unit test it outside of the container, while the injectable configuration allowed us to more easily test the way the agent created and added a Configuration MBean that we were so desperate to refactor.

Although it has much more work to be done to make it that much less detestable, it is one step closer to being more easily unit tested and therefore much more refactorable. On a side note, there was a huge smell that indicated the classes around the ManagementAgent were so detestable when I remembered that the package it was in had been excluded from the clover target which effectively boosted the code coverage numbers. Avoid detestable classes because it will increase the cost of future change!