productivity, Software, software development process, standards, testing, trends, usability

To Beta or not to Beta – That is the question

Whether ’tis nobler in the mind to suffer the slings and arrows of outrageous bugs, Or to take arms against a sea of defects, And by opposing end them.” (with props to Bill S.)

In the past few years it’s become more and more acceptable to release “Beta” software to the public – almost as if it was a production release.

The reasons for that I believe are manifold but boil down to
1) Gain user feedback
2) Release early to gain “mindshare” and/or get first to market.
3) Your QA process or team isn’t that great (or your unwilling to spend money on them) and you’d rather have users do your testing for you.
4) You need to gain the confidence of your customers / investors in what you’re building.

The number one proponent of the Beta, I must say is Google. I’ve been a Google Docs user for well over a year now and I love it – but it’s still in Beta. The one thing I don’t love is the FREQUENT UI changes in direction though – but hey it’s a Beta and it hasn’t lost a Document or Spreadsheet of mine yet.

But it’s clear from using what Google call a “Beta” that their goals are really predominantly #1 (user feedback) and probably to a lesser extent #2 (mindshare). It’s been very well tested (internally) before it hits the public. You can read more of what Google think about Betas here.

So the quality of their Betas is quite high (see also gmail) and a Beta for them is probably a production release for 90% of everyone else.

Here’s the problem though – in making Beta’s “popular” I think they (and others) have lowered the bar at least insofar as management can now look at it and say “Well if Google did it – why can’t we?”. So there’s a tendency now to ship lower quality software and at the last minute people decide to slap a “Beta” label on it if it’s not up to snuff so that they can declare victory. Then they hope people will use it as if it was production quality.

Personally I think software professionals should be using a public “Beta” ONLY as a last resort. If you need to gain user feedback – try not to be cheap about it. Get a bunch of potential users in a room and have them use your product – try not to prime them – just watch them. Video them. Understand what are they trying to do – how does that align with your product? Can you make your application so easy to use it doesn’t need a manual? That should be the goal (although that might be ultimately unattainable any progress in making your application easy to use is good).

If the reason is #2 (to be first to market) then I think you don’t understand technology trends. Neither Google or Internet Explorer (or Firefox) were first to market – look where Yahoo! and Netscape are now.

I guess I never really “got” the whole first-mover advantage thing. Think about it:

  • Apple vs. Windows (and back again)
  • Ford vs. Toyota
  • Betamax vs. VHS
  • Atari vs. Nintendo
  • WordPerfect / WordStar vs. Office
  • Friendster vs. Facebook vs. MySpace

The anecdotal lesson I got from these cases was to NOT be first mover and learn from the other guy and where he fails.

Anyway if you’re in the position of #3 (you’re not investing in your QA team/process) then that’s a sorry state of affairs. Although we live in a world of finite resources – finite dollars and hard-to-find tech experts so I guess it can be excusable sometimes. But if you just punted to force your users to do the bulk of your testing work then shame on you.

If you’re in position #4 – releasing a Beta to the public to gain confidence well it’s hard to argue too much with that given the sorry state of “production” software these days (*cough* Vista *cough*) people’s expectations are sadly low so its understandable people (especially investors, customers) want some reassurance.

Don’t get me wrong on this though – I’m not the type of guy to wait until the product is perfect. It’s more a question of what are your motivations and are you being lazy in releasing a Beta? If you want user feedback – GET USERS and GET THEIR FEEDBACK! Don’t ship junk!

After doing some Googling I came across a blog article with similar sentiments
A call for revolution against Beta Culture

I’m mostly tired about the fact that it seems that we all have given up. Tired because . . . . in reality, it’s laziness and a poor job on the manufacturer part that we have accepted without questioning. Instead of calling foul play and refusing to participate, we keep buying.

That’s the key: We have surrendered in the name of progress and marketing and product cycles and consumerism.

Right on man – it just doesn’t feel right. It feels lazy and short-sighted.

Here are some other thoughts by other folks

So here’s my question to you, dear reader, what is your opinion on Betas? Useful software engineering technique or cop-out?

Standard
productivity, project management, software development process, standards, testing

Automated Regression Testing: Why, What and How

Having to wear the hat of three different roles (Architect / Manager / Developer) you find there are few things in software development where there isn’t a significant trade-off depending on your role and it’s viewpoint.

For example when I’m managing, things like refactoring take a back seat to rolling out new product – even though I’m aware of the positive impact of refactoring. When being an architect I’d rather minimize code duplication (or triplication) – a long-term gain to team productivity but at the cost of product in the short-term. When developer I’d rather be focused on developing the cool new product than bug fixing. There’s few things I can wholeheartedly stand behind when having to wear all three hats.

However good automated regression testing is something that I’m pretty sure everyone can agree on. It’s usually not a huge investment of time but the payoff is large and grows over time – like a savings account.

From each point of view

  • Developer –> Less Time bug fixing. I can go home before 7pm. Yeah!
  • Manager –> Better quality product, risks identified earlier. Less screaming customers! Yeah!
  • Architect –> Great way to support refactoring with minimal product risk.
  • QA –> Less manual drudge work.

Probably several of you are asking – “OK but what is a regression test?”. Put simply it’s testing that finds bugs in code that used to work in past versions.

WHY
As mentioned above, regression testing is first and foremost a “risk reduction” exercise – you want to find bugs in code as fast as possible with minimal effort (automated!). This becomes more important the longer your product has been in production – no-one wants a release to be “three steps forward and two steps back”. You want your product to always be increasing it’s value to your user base. Bugs will happen – you just want them to either be minor ones or stuff in your new code – not the old stuff that people rely on to get their job done.

In any event, people’s expectations for software these days are sadly low (Thanks Microsoft!) so delivering anything reasonably reliable gets noticed.

It also acts to reduce the “drudge” work of manual testing. That work is also subject to human memory – unless you have all the test cases written somewhere – are they all up to date? You sure? For the most part the answer to that is no.

Similarly automated regression tests also act to codify and formalize one’s experience so, God forbid, you lose a QA person, a product manager, developer etc. You don’t lose the entirety of their knowledge.

Although some would argue this makes those roles more replaceable – in my experience it acts to free up QA, Developers, Product managers to do more valuable – and LESS replaceable work.

It also helps your team be “more proactive and less reactive” (forgive the management speak). But as we all know – the more your team spends fighting fires the harder it is to have a truly enjoyable work place. Or at least that’s my opinion.

HOW
So how do you “regression test”?

0) Stop Here!
First I’m going to assume some things – first and foremost that you have a source control system. If you don’t then that’s the first order of business – get one! SVN, CVS or whatever (personally I prefer Perforce – actually I love it).

I’m also going to assume your team or organization cares about product quality – no problem right? Think about it though – think about your past work experiences. I’ve been in several situations where there was no will to do any regression testing of any real merit – I tried to fight the good fight but sooner or later you get labeled as obstructionist. True you can’t spend all your time on this – but if you can’t spend a few hours per week per developer you’re in for trouble. I’m sure I’m not alone in this experience.

1) Unit Tests
Well JUnit test cases are an obvious place to start. So obvious I won’t spend time on them – the benefits and myriad and have been discussed ad infinitum (nauseum) here and elsewhere.

The key though is to remember to also focus on unit testing from a product point of view as much as one can – not solely a code point of view. Although code coverage tools are helpful too – 100% code coverage doesn’t really mean as much as one would hope (see this great article by Andy Glover).

Also remember you don’t just want to test functionality (both positive and negative cases) but also, if you can, performance / scalability and security.

2) Automated GUI tools
Assuming your product has a GUI you’ll probably find yourself or your QA automation team writing scripts in some tool such as Segue Silk, HP/Mercury WinRunner, Quick Test etc.

These tools are good because it’s very hard to unit test a GUI. The number of paths through the GUI are myriad for anything more than the simplest UI.

However these tests are often much slower than unit tests and require significant resources – both people and machine to run.

Again don’t just focus on tests for functionality but also look at testing performance/scalability and security (and I’m sure other things too)

3) Projects-specific ways
Often you’ll find ways that are specific to your software or project. Some examples are below

EXAMPLES
Two examples I’m very proud to have been a part of are described here.

The first was a product where my firm transmitted data to another firm – financial information about products we had for sale. The products were then advertised on the other firm’s web site.
The key problem was that the data was constantly changing (think stock prices) so the information had to be pretty current (not totally real-time but a gap in minutes was about the worst we would tolerate).

Fortunately this customer had a test system which we could attach to – upload data and verify that any changes we made would still would work. How to tell it all worked as it was supposed to? I wrote a Java program using HttpUnit that would login to their web site – find the appropriate product pages, parse the HTML and pull out the prices. Then it would compare that data against what was in my local DB (the data I was supposed to send them).

Once I had run that for an entire day without issues I was extremely confident that all was right with the world.

Also a nice upside was I could run that SAME program against our production system (it’s read-only after all) to verify that production was fine.

Now the REALLY cool thing was when something happened in production e.g. network outage or some remote problem typically I could inform my user base and my management very quickly. Often they would know before our business partners were aware that THEIR system was having problems. It’s really nice to be able to have that level of confidence in your product and your users and management notice too let me tell you.

Another good example was more typical to software product firms where one has many customers running the product. Typically as we’re solving problems with this product we would get copies of their databases to debug issues. In turn we would take several of these customer databases and run them through nightly regression tests.

The test would compare the current release vs. the last known release (considered the “gold copy”). Not only would we diff results but also we’d compare execution times. And although the environment was not totally locked down for a true performance comparison – a 20%+ discrepancy of performance for > 1 day was typically a sign of a potential performance issue in something in our code or the data model, indexes etc.

OK enough bragging . . . let’s talk about some best practices.

BEST PRACTICES

#1) Find and Test the Gaps
Testing is never done and neither will your regression testing. Naturally you will (or should) want to test the riskiest pieces first – places that have largest impact if they break and/or break frequently. Often too you should use customer feedback and bug reports to help guide your list of functionality to add to the test. Look for patterns – key areas of misunderstanding or bugs. Code coverage tools can also be helpful but don’t rely on them to tell you when you’re done.

Keep a prioritized list of areas to cover – start at the top and work your way down.

#2) If you’re not finding bugs ask why?
One way you’re regression test can stop finding a lot of bugs is if it’s out of date – if you haven’t been spending time adding to your test suite (you’re adding more functionality say?) then you’re short-changing yourself. With every release of your code – your regression test should grow or improve.

Another is if the tests being created aren’t aligned with what’s known for risky / bug-prone areas.

Another is when your developers are so damn good they don’t have bugs anymore – but we all know that’s not all that common. But often you’ll find that’s because they run the regression themselves when they realize how valuable it is.

#3) Have dedicated hardware
You don’t need the biggest, baddest machine – often a recent late-model desktop will suffice in most cases. But you need this to do #4

#4) Run them all the time or at least nightly
Your tests should be running all the time or at worst – once per night. Once your tests are big enough there may not be enough time in the day on on existing hardware – so you may wish to keep some long running lower priority tests for the weekend or alternate test suites every other day.

#5) When you max out – throw hardware at it
Hardware is a commodity – it’s cheaper to buy some high end Solaris hardware for $10k than it is to take two months of a developer who earns $100k per year plus benefits to speed things up. So when you start to max out your current regression test machines throw hardware at it first – then improve the performance (unless there’s some blindingly obvious quick fix in software).

#6) Critical tests first

In the spirit of “fail fast” and risk mitigation – you first want to perform the tests that will find the most critical items or test bug-prone pieces of code.

#7) Automate Result Interpretation
Once the results from your regression test are ready it should email relevant people and provide a synopsis of the results. A daily regression isn’t very useful if it takes an hour to figure out if you passed or not. Eventually no-one will read it.

#8) Add tests continuously
Don’t wait for a particular “phase” of the project to add more tests – do so continuously otherwise you’ll find that time suddenly disappears and then you’re playing catch-up.

#9) Don’t reinvent the wheel – use tools
If you’re going to automate don’t waste time – use the all the tools you can. There are so many great tools out there from open source to commercial (although I must say the commercial tools I find VERY expensive compared to their utility).

And there’s probably a half-dozen I’m not aware of that I hope you, dear reader, will tell me about.

Don’t forget static code analysis tools too (See “Analyze this – put your code on the couch!“) to help find bugs (e.g. multi-threading) that your regression tests might miss.

Having a great suite of regression tests brings great confidence for a team of developers – who are often frankly a pessimistic lot – that can mean you and your team will stand out in the crowd and separate the true engineers (who care about delivering a quality product) from the cowboys.

(p.s. Thanks to Rick for the push!)

Standard
productivity, programming, Software, software development process, standards, testing

How to file a good bug report

One of the first lessons, hard lessons, you learn coming into the world of software development out of college is how hard it can be to understand bug reports.

Variously they can be vague, misleading, inaccurate, confusing or best of all – misunderstanding a feature for a bug (the latter often points to usability issues).

Having endured many of these and now doing a fair bit of testing of my current application, I try to “be the change I wish to see in the world“. So I’ve come up with the following scheme for bug reports.

#1 Start with a good short bug summary
For example:
“Data Entry screen disappears after entering certain unusual keystrokes”

The good part of this is a manager / team lead gets a quick idea of how serious this issue is (screen disappearing – bad!) where it occurs (data entry screen) and what caused it (unusual keystrokes). Useful in understanding just how serious it is and how soon it should be reviewed and/or fixed.

Next up you need to focus on the needs of the developer – basically instructions so the developer can reproduce the issue

#2 The *exact* build you are using
e.g.
March 27th 18:05 PM

Sometimes developers get dupe issues with related if not similar symptoms and having the exact build they can often realize “Hey that’s that same issue I fixed yesterday” and they can then tell the tester – try the 28th build because it’s related to issue X we resolved.

#3 Environmental Aspects
Including
– What machine the different parts of the system were running on e.g. web server, GUI etc.
– What database you were pointing at and DB login if appropriate
– How you installed the build e.g. options
– Your GUI login if appropriate
– If you can, it’s really awesome to leave that build around and up-and-running so a developer can come over to your area and check it out for themselves. Not always possible but for those big critical issues it’s a real time saver.

#4 Instructions to see the bug
The steps need to be detailed, step-by-step.

Often when I report a bug I spend a few minutes trying to get the least number of clear steps to reproduce an issue. This is important not only for the developer but for the person who subsequently tests the fix perhaps minutes, day or even months later.

You don’t want to be too detailed “point your mouse to the ‘Send’ button and left-click” or too vague “enter some data and hit ‘Send'”

1) Login to the GUI
2) Go to ‘Tools > Data Entry > Advanced’
3) Select the ‘Schedule’ tab
4) Enter ’03/04/08′ and then without saving try to tab off
5) You get a System error (see attached)

5 Supporting Documentation
Screenshots are great ‘proof’ – especially for those developers you may know, who try to reproduce the issue for 5 seconds and then say “Unable to reproduce” and cancel your bug which you spent quite a bit of time entering. Very annoying!

Some folks who have long complicated steps often choose to add video capture too which is great (but bulky).

Logs are great too especially when they contain more useful errors related to things the developer can grasp e.g. Malformed SQL on line 223 of DataEntry.java.

Often these are attachments and as a technical lead I often trawl through the logs to find the most important lines e.g. often the first stack trace and then copy-and-paste that into the main bug description.

Other things you need in a bug report
– A unique identifier for this bug report
– Priority – Stick to High, Medium and Low – beyond that lies madness! 🙂
– Severity is optional – often I find it confused with Priority for various reasons- again three levels should suffice – major, moderate and minor/cosmetic
– Who created the issue and when?
– Who is assigned the item?
– Who is the tester going to be?

Good bug reports take time. But it’s worth it – I figure for every minute I put in to the report to make it clear and concise I’m probably saving 5 to 10 minutes of a developer’s time and then more for the person who might have to test it (might be me 6 months from now).

As a team lead also I’ll reject reports that lack these details. It’s funny I’ve known some experienced QA folks who just can’t seem to get this right – it’s very frustrating to start a back and forth – which builds is this – please add logs – can you add a screenshot?- and then there are some who write them so well it just becomes a slam-dunk for the developer. Often they’re the ones sitting right beside the developer – they’ve each learned how each other works – how to keep each other productive and keep frustrations to a minimum. That’s good all around.

Standard
programming, Software, software development process, standards, testing

4 reasons it sucks to be in QA

Well that’s my take on it folks – of all the roles in the Software Development Life Cycle probably QA has it worst. Managers, Architects, Developers, Business analysts – no-one takes as much BS or has such a thankless role as the valiant folks in your average QA team.

Now I hope most of you reading this will disagree but I’m betting there’s a lot of nodding heads out there (probably mostly from folks in QA).

What are the main reasons for this you say? There are four as I see it:

1) Respect
QA tends not to get respect from people in other roles – but most especially and most oddly the least respect (most disrespect) comes from software developers. Personally I find this strange that developers have such disrespect (sometimes even open and outright disdain) for those tasked with ensuring the quality of the product being delivered.

I think a lot of developer frustration comes from the questions and problems that arise out of the QA team/group. Yes, often QA folks don’t understand the ins and outs of an application. If that’s because someone in QA doesn’t want to learn then that’s a worthwhile beef but more often than not the QA team are STARVING for information.

Often they’re brought in at the last minute, given a vague, incomplete and out-of-date spec and told “Hey go test this!“. Yes the developers had the same spec and were told “Hey go code this!” but they’re finished building out the app so they’ve (hopefully) fleshed it all out at least in their heads and in the software they’ve built.

Developers deride the QA role – “What do those guys know? They’re just testers!“.

That’s just the wrong attitude. These guys and gals are the ones who, at the least are helping to make the product (not code folks – product!) better, and at best saving your ass from being fired for shoddy work. You and they are on the same team though you may not realize it. Try to remember that.

Another reason that I feel developers beat on QA is that the developers get beat on themselves (think Dilbert) and like some bullied kids they look to take it out on the only one’s they can – someone weaker – not managers, not architects, not the business analysts, not other developers – who’s left? QA!

I’ve seen it many-a-day – the self-righteous attitude developers take in correcting QA or better yet informing them that their “bug” won’t be fixed because it “works as designed” or they spent 5 seconds trying to reproduce the bug and could not.

I’m not saying “works as designed” or “unable to reproduce” are a bad reason to kill a bug – just the attitude that goes with it. Call the tester – explain why it works that way – should the docs be updated to make that clear? Possibly! If you can’t reproduce a bug maybe there’s some context or other missing information – maybe it’s particular to the tester’s environment. Just blowing things like that off might make a developer feel good but it diminishes the overall product and the team too. Take the time to do it right – a phone-call or walk-by will take 5 minutes at most.

2) Responsibility vs. Power
The QA team have a very important responsibility – they are the gatekeepers of product quality. At least in theory anyway! Also quality is a hard thing to identify or quantify. Is it the overall user experience, the number of bugs, the number of critical bugs, how do you define “critical”? Just too many subjective things. Oh and usually they’re understaffed and/or under-tooled.

However for all this responsibility they have the least power. In the hierarchy of management structures QA comes pretty much last.

Everyone else thinks they can do the QA job – how hard can it be? But the reality is very few people can do QA right. And especially not developers! We are our own worst enemies in this case – we use the application like we coded it not like it was meant to be used.

3) Last to be hired and First to be fired
In the boom and bust cycle of software QA folks seem to be the last to be hired – usually towards the end of the boom when all your new customers start to complain about the bugs from all the newbies you hired at the start of the boom. But then when the bust inevitably comes QA folks are first on the chopping block followed by middle managers. No wonder there aren’t many experienced QA folks about – again it’s a widespread lack of understanding of the importance of QA and testing in the software process.

4) Paradox of excellence
The “Paradox of excellence” is something we’re all familiar with but may not know it. Since the art of software (it ain’t engineering or science yet) is not well understood, few outside of software can understand how hard it is to do software “right” – with few bugs. It takes a long time. Therefore when software is done right people don’t perceive the absence of bugs – they just see that the process seemed to take forever to complete.

Basically the “paradox of excellence” states that you don’t get credit for problems that never happened. Typically in the normal software shop when bugs happen and they are fixed fast by developers the developer gets kudos. Who gets kudos for the lack of bugs in a release? No-one.

So if QA does their job right – no-one notices. The same is true for developers to an extent but they can usually redeem themselves if and when bugs do show up. QA have no such opportunity – if they *do* spot issues they becomes “spoilers” for the party giving the bad news no-one wants to hear.

With those four issues facing you as a person in QA – lack of respect, little power, no praise, fear of being laid off, how much motivation would you have every day?

In my opinion a rock solid QA person is one of the most critical roles on a project. In fact in my experience the best QA people know the application better than the developers, the managers, the analysts and even the users. They know the ins and outs – breadth and depth and know where most of the bugs pop-up! I wish most developers were so aware.

Solutions?
How do we resolve this problem for folks in QA? There are two steps – the first easy and the second not so much:

1) Co-locate QA and Developers
Have developers and QA sit side-by-side and work together closely throughout the entirety of the software lifecycle. Make them truly part of the team! Have lunch together!

Physical separation of QA from the dev team is a bad idea. Having separate reporting structures for Dev and QA might be good since having same reporting structure creates a little “conflict of interest” – management understandably want good news, QA are rarely bearers of good news – but it’s news that needs to be heard!

2) Developers and management need to snap out of it!
Frankly this treatment of folks in QA is one of those little “secrets” in software that we should be ashamed of if we consider ourselves to be “professionals” in the true sense of the word.

Developers and management need to respect the critical role of QA, the complexity of their job and most of all to drop by their cubes and say thank you for all their hard work they do without much praise – day-in, day-out. Your product is better for it, the industry is better for it (and could do with much more of it) and thus the rest of us managers, architects and developers are better for it.

Standard
code quality, j2ee, java, programming, Software, standards, testing, XML

Java Worst Practices

We’ve all read those “best practices” articles which are great and useful. But after the good reaction to my “Java Exception Handling Anti-Patterns” article I thought I’d continue on in the same vein – things NOT to do.

So here’s a list of “worst” practices – the things I see many-a-day that are particular pet peeves of mine. Frankly I’ve made these mistakes myself quite often when I was less experienced so they’ve become a kind of personal checklist for my own code as well as for that of others. I’ve touched on some of these issues before but have added some more and drilled-in a little more.

Of course these days I use my code checking tool trifecta (Checkstyle/PMD/FindBugs) to do it faster and more reliably but still it’s good to stay sharp and do it manually every so often.

1) Exception Handling I: poor catch blocks
See the blog entry “Java Exception Handling Anti-Patterns” for a number of such anti-patterns. How to handle errors correctly is critical and not altogether that easy in Java (thus the whole checked vs. unchecked exceptions debate IMHO)

2) Exception Handling II: missing or bad finally blocks

  • If a finally block is absent in a try{}catch{} combo, is one needed to release resources?
  • Is there an exception thrown in the finally block that bubbles out? Talk about cause for confusion when reading the code!
  • Is there a return inside a finally block? Talk about even more cause for confusion!
  • Do you have returns *AND* uncaught exceptions in your finally block? Check this link out. Exceptions that just disappear into the aether? Yikes! I’d guess 90% of developers (including myself) got that wrong.
  • If there are multiple methods called in a finally block, and any of them can throw an exception, will the other methods get called e.g.
    .
    .
    }
    finally{
    try{

    if(obj1!=null) obj1.close();

    if(obj2!=null) obj2.close();

    } catch(SomeException ignored) {
    }

    }

    In this case if an exception was thrown when closing obj1, then obj2 would not be closed creating some problem such as a memory leak.

3) Logging

  • Too little? App crashes and there’s nothing in the log file.
  • Too much? App crashes and you need to plow through a 5 GB log file (just for that day!)
  • Wrong level – debug vs. info vs. warn vs. fatal?
  • Same log entry repeated many times
  • Using Exception printStackTrace() – Do not use printStackTrace except for the simplest programs – use you logger and log.error(“Some Text Here”,e); to log that important and all-too-helpful stack trace information information to your log file for posterity.

4) Classes / Methods too big
Big classes and big methods become inevitable complexity sinks – the code becomes very very hard to maintain. Create utility classes, break-up the functionality – do some refactoring to make it easier to use, extend, adapt and especially debug!

5) Comments in code

  • Too little?
  • Too much?
  • Comments which are no longer relevant or are out-of-date with respect to the code
  • Comments which are useless/redundant e.g.

//set number of accounts to zero
numAccounts=0;

FYI some best practices in this area are listed here on Wikipedia. Most notably:

  • Comment why not what – make your intent clear.
  • Make your comments the code – if your comments are clearer than your code make your code look like the comments.

For example here’s a pattern typical of code I often find in a review (even of my own code)

//check system Ok for startup
if(switch1 && switch2 && (switch3 || switch4))

now replace that but as follows and drop the comment

if(isSystemOkForStartup(switch1,switch2,switch3,switch4))

now you’ve got a nice utility method that you can re-use plus one less comment which means one less place where you have to keep the comments in synch with the code

6) Switch Statements

  • Missing default: – just put something in there even if it’s a log.warn(“This should never happen”);
  • Missing break; and the resulting “fall through”. God those bugs can be nasty to track down.

I usually write the “default” first to make sure it gets in there and try to give visual cues to highlight missing breaks like trying to line them all up vertically.

7) catching java.lang.Throwable
There’s a few cases where I think this is OK . . . . okay just one . . . wrapping a complete application with this so you can log.error() / System.out.println() if something bad happened that for some reason wasn’t handled.

But apart from that, exactly what do you plan to do with VirtualMachineError or OutOfMemoryError? Just carry on?!?!?!

8) Using exceptions as flow control
Sigh! It still happens every so often.

9) Not removing commented out code or unused classes
I’ve done it myself but usually I open a bug report to myself to take it out (eventually). Sometimes it’s hard – you’ve written some good code that you might use some day just not now and you want it in there – but hey that’s what Source Code Control is for.

10) Complex code with no unit tests
Don’t even get me started! Yeah yeah I know the refrain – we don’t have time but come on – a few unit tests? Please!?!?!? Just some happy-path cases?

11) Duplicate Code
We’ve all done it – we just need to make sure we undo it – refactor! If you’ve got production code and 1 or 2 dupes I can make an exception. 44 not so much (trust me I’ve seen it!). Oh and the excuse here – “Well we’ve got 44 separate JSP files” – turns out it was really one JSP file with some parameterized pieces of code. About 5000 lines suddenly became 250.

12) In multi-threaded code, using Object.wait()
That is the call to wait with no timeout – so the user or calling application can just wait forever eh? Oh and the bugs it causes – your code just sits there “dead”, there’s nothing whatsoever in the log file and then you’ve got to find the one thread in your 500 with the endless wait.

Every time I get one of these I cringe, cancel family vacations, hunker down and get stuck in.

By using a timeout you force yourself to think about what is a reasonable thing in most cases – what if that shared resource is simply not available? If you don’t do this, effectively you just expect “the other guy” to worry about giving it back and abdicate your own responsibility.

13) Coding Standards that are directly in contradiction to accepted and known Java standards.
For example – not only allowing class names to start with lower case letters but ENFORCING it (yup – been there)

14) Enforcement of Coding Standards that is overly picky
I could pick an example (e.g. placement of braces, tabs vs. spaces) but I’d probably evoke a bazillion flames! Oh and best of all – often these rules are enforced before important things like unit tests, code coverage – those things related to code that works!

15) Overuse of XML
For example – storing XML in a database and then wondering why indexing on the contents is slow?

16) Wrapping Java platform APIs
For example – wrapping JDBC with your own API. Now I’m not talking a DAO or some abstraction layer – I’m talking about a class-for-class, method-for-method wrapping!

Oh I’m sure there are others but these are the ones I look for during a human-based code scan. I can’t scan my own code because I’m terrible at it (and lazy whenever I spot anything – just too easy to look at the other 10 things pressing on my To-do list). The best thing to do here is use Checkstyle/PMD/FindBugs and have someone else prod me.

Standard
code quality, j2ee, java, programming, Software, standards

Java Exception Handling Anti-Patterns

The following article addresses one of the hardest things for new java programmers to get right – how to handle exceptions – or more accurately the article talks to how *NOT* to handle exceptions.

Link

It was published in 2006 and I’m surprised I haven’t seen it before now as it’s really quite awesome (I came across it using Del.icio.us)

Anti-patterns they describe include

1) Log and rethrow
2) Throw the plain old generic java.lang.Exception
3) Throwing the Kitchen Sink
4) Catching java.lang.Exception
5) Destructive Wrapping
6) Log and Return Null
(Side note: I firmly believe you should NEVER return null from a method unless you really enjoy debugging NullPointerExceptions or giving them to other people’s code – yah I know the Sun spec has several such cases in the core API but still . . . . .)
7) Catch and Ignore
8) Throw from Within Finally
9) Multi-Line Log Messages
10) Unsupported Operation Returning Null
11) Ignoring InterruptedException
12) Relying on getCause()

Two other great Exception handling articles (more from the POV of what to do than what *not* to do) are

a) Patterns for Generation, Handling and Management of Errors by Andy Longshaw and Eoin Woods
b) Best practices in EJB exception handling by Srikanth Shenoy

I particularly liked the Longshaw/Woods ideas of “Log at Distribution Boundaries” and “Split Domain and Technical Errors”

Standard
design, software architecture, standards

Symptoms of poor software architecture and development – the broken windows theory

The “Broken Windows Theory” is a concept from Criminology that maintains if small crimes (e.g. broken windows) are not addressed then people will take it as a laissez-faire attitude towards crime and feel emboldened to commit bigger crimes.

Similarly, I maintain, in Software if you ignore the “small” details (e.g. logging, error handling, resource handling etc.) you’re in for a rough ride when it comes time for testing, deployment etc. Martin Fowler, talks about ” Bad Smells in Code” (a term apparently coined by Kent Beck)
which talks about similar signposts for bad coding.

Andrew Hunt and David Thomas use “Fixing Broken Windows” as a metaphor for avoiding software entropy in software development in their book, The Pragmatic Programmer Addison Wesley, 1999. Item 4 (of 22 tips) is “Don’t Live with Broken Windows“.

So here’s my partial list of majorly bad smells, which, while code-based, tell me that
if these details aren’t addressed there’s probably some serious design and architectural issues there too

#1 Poor, inconsistent or no Error Handling
Worst of all is “swallowing exceptions” for example empty catch{} blocks or just dumping the Stack Trace. At least there should be a call to the logger to dump an error or warning to the log file. The text of the message should say
i) What happened (e.g. what exception was thrown)
ii) Why? (e.g. input parameters, which database was accessed etc.)
iii) What’s the result (e.g. data corrupted, will retry again, etc.)
iv) What line of code threw the exception (log the stack trace too)
v) If there’s an embedded exception log that too

On a related issue there’s the whole C# vs. Java (Unchecked vs. Checked exceptions) debate. Whilst I agree that many times a caller can’t really handle an exception much beyond logging it, or handing off again, I believe that just moving to unchecked exceptions is a cop-out to an extent. There’s some good writing out there on Exception handling and how to do it nicely and consistently see:

i) Longshaw & Woods: Patterns for Generation, Handling and Management of Errors
ii) Srikanth Shenoy: Best Practices for EJB Exception Handling

Good exception handling is hard to do (as I’ve learned from painful experience) but it’s a very important part of a coding standard.

#2 Poor, inconsistent or no Logging
Highly correlated with #1 – often poor error handling goes hand-in-hand with poor or no logging.
It’s amazing how many times I’ve seen big complex Java code and no logging – then when the software is deployed to the customer and it breaks – surprise, surprise no-one knows what’s going on when there’s an Exception thrown. Then the developer has to reproduce it somehow.

It really saves time to be able to get a good stack trace in a context of what happened before and after (also in the log file). Saved time is saved money for your company and helps improve customer relations by enabling faster issue resolution.

#3 Poor Resource Handling
Related to #1 and #2 – watch in database code if people release their resources using finally{} blocks. If they don’t it’s a recipe for trouble and a sign that code is not being reviewed for “obvious” potential problems.

Similarly if people are just getting database connections “willy nilly” rather than from a central pool, again not a great sign.

The same principle applies in all resource handling e.g. JMS. I find lately I’m often initially skeptical of try/catch blocks with no finally.

#4 A build process that is not automated
Not automating the build process causes “busy work” every hour of every day for developers. It’s a time-sink that needs addressing. It’s also a risk-area as you potentially have different developers building and deploying in different ways and what works on one developers build then doesn’t on another’s build.

I’ve seen build & deployment processes that took up to an hour – the cost to the team (of 16 developers!) in efficiency was terrible and the senior developers spent many hours debugging issues that turned out to be environmental (there was one property file per developer, 90% of which were the same and someone forget to set a value in their property file etc.) .

We automated the build end-to-end (compile, create JAR, deploy to WebSphere, install properties etc.) and shortened the time to 7 minutes. We migrated the common 90% of the property files to a single files that one person was gatekeeper for. The improvement to the team from just a morale point of view was palpable. The increase in efficiency to the team was quite evident to developers and managers alike.

#5 Poor or no Documentation
See my other blog entry “Why documentation matters – intent and abstraction” for why I think this is important.

#6 Few or Broken Unit Tests
As an Architect I find that unit tests are very telling about a Software Developer’s level of “responsibility” – not necessarily how good their code is, but how much they care about the success of the project and of the team. Unit tests are important to prove to yourself and others that your “unit” works and operates the way you think it should (not necessarily what was intended though). I can quickly scan a set of unit tests and see what the developer has tested, and if there’s any difference between us on how we think the unit should work, without reading the code. That’s really the idea behind a unit test – verifying the satisfaction of a contract (see “Design by Contract“).

#7 Big Classes
Classes longer than about 500-750 lines of code (not including comments) are usually a sign that a class is trying to do too much. This suggests that the OO design was lacking (if there was one) and a separation of functions would be advised. I’ve seen classes with over 4,000 lines of code that were very scary to maintain just due to their size (there was no unit testing of it either) and it was just begging for a refactoring.

Anyway those a few of my top “broken windows” and it amazes me how often I see them and how often they correlate with larger architectural issues that lead to poor maintainability, poor performance and scalability, etc.

What “broken windows” have you seen in your time as a developer / architect or manager? What are the symptoms and how should they be fixed?

Standard