Search This Blog

Old (Bad) habits die hard

Recently I was reminded painfully of the fact that habits you have taken to once hardly ever get laid off.

I usually consider myself someone who tries to write software after I have thought it through. I do not mean
"over-engineering", "over-abstracting" and "over-prepare-for-anything-that-might-ever-come'ing".
However I also believe that starting hacking blindly is not a good thing either. And I
try to write "nice" code, even though it might be a little more work, as long as it is easier to read or
just plain more stable (which is often the same).

Sometimes however, especially under a tight schedule, by force of habit I (and probably any developer out
there) tend to do things that upon later review make me feel deeply embarrassed. Just so I did a couple of
weeks ago...

I had to write a component that translates data from a legacy system, stored in plain text files, into a
relational database, accessed through an object relational mapping layer. Each entry into the SQL database
is generated from single text file. The information used as the primary key is encoded into the filenames.

For some reason I cannot understand anymore today, I decided to keep track of the files I had already
processed by appending their names to a new plain text protocol file. At the time I probably thought it
was quicker to implement than to come up with a new kind of protocol value object to store it into the
database for each entry. However in retrospective I doubt that this approach was really faster to implement.
(Even worse, this code is deployed into an J2EE application server where you are not even really allowed
to do file i/o if you follow the EJB spec.)

Anyway, this translation component includes a polling mechanism that regularly inspects a directory for new,
unprocessed files. While during my tests nothing looked wrong, after some time in production the processing
(better: the polling) became continously slower, as the list of files already processed
was growing longer and longer. So the time to find out if a file was new or still had to be processed
gradually increased. To make matters worse, the number of file names available is limited by the design
of the legacy program, so they start to roll over after a while, making the poller believe that a file had
already been processed and could be skipped, while in fact there was new data in it.
I would have had to include the file modification timestamp into the list of already processed items
and compared them for every poll cycle as well to make this work again.

So in the end I had to refactor the whole thing and roll out an update of our application that
stored the necessary meta-information into the database server to get an acceptable throughput again.
To avoid the the file modification date check we additionally we implemented an archive mechanism for
the legacy files to keep the number of items in a single folder limited and the names unique.

However all of this shows that people tend to fall back into old habits, once they get under
pressure. It can be really hard to notice this in time and make yourself do it "right" from the start.

Here is my private list of things I notice people (including myself, of course) doing time and
again despite knowing better:

Use files instead of other, more suitable forms of storage

Hard code strings ("I will come back to I18N-ize this later...")

Include debugging output via System.out.println instead of through the logging mechanism

Add checks for null's in places where you should not get any null in the first place instead
of trying to find out the real cause.

Change the code, but not the documentation - it is always fun to look for a bug or unexpected
behaviour that is caused, because a method does not do what you would expect from its comment

Change the behaviour, but not the names (of methods, fields, variables...). This should never
happen, given the excellent renaming support modern IDEs offer.

Feel free to add to this list anything that comes to your mind :)

Get link

Facebook

Twitter

Pinterest

Google+

Email

Other Apps

Comments

Popular posts from this blog

Today I had to look at a piece of code a colleague had written, using my XPathAccessor class. She used it in a servlet which gets XML formatted requests. As those are generated by an external 3rd party tool we agreed on some XML schema definitions. Everything they send us needs to conform to its corresponding schema, each reply we send gets validated against a different set.In order to allow independent testing on either side, we provided a little test kit that allows testing our system without having to set up a servlet engine. Basically it just takes a file, reads it into a String and hands that to the handler.First it gets parsed without validation. This is necessary to find out which type of request we were send (the address is the same for all of them). After the root element is known, it will be read again, this time using the right schema to verify the request.Once that is done, some reply is put together and sent back to the client. So far, so good.When I looked at the code I …

(Also see the follow-up post about some progress)Today I was (again) facing a log file from a machine that had for some reason not been able to start a temporary MySQL daemon during the night to prepare for a streaming MySQL slave installation. The necessary 2nd daemon had created its new ibdata files, however just after that aborted the startup process with the following message:Can't start server: Bind on TCP/IP port: No such file or directory
071001 23:09:55 [ERROR] Do you already have another mysqld server running on port: 3310 ?
071001 23:09:55 [ERROR] Aborting
071001 23:09:55 [Note] mysql\bin\mysqld.exe: Shutdown completeAs you can see, the port is a different one from the default MySQL port, so I can be sure there was no conflict with the primary instance. Even more curiously the same process has been working on that and other machines flawlessly for some time. However I remember having seen this message once before, but back then I did not have the time to look into it any…

Some words in advance...Recently I wrote about multi-threading problems with java.util.Calendar and java.text.DateFormat. The last sentence was So maybe it is time to search your code for all static usages of the Calendar and various ...Format classes, before you start getting strange errors.Searching code is not very practical, especially if you do it manually. Everyone knows you can look at code for hours, without seeing an problem - and as soon as it has reached production systems it starts breaking up in various ways :-)Fortunately smart and reknown people have devised ways of making the computer look for bugs automatically. Amongst others, FindBugs is a very nice - and free - tool that analyzes your Java application's compiled bytecode and looks for numerous so called bug patterns. Those patterns are divided into categories, such as "Bad practice", "Correctness", "Multithreaded correctness", "Performance" and some more. Each of them lo…