Thursday, January 29, 2009

Java Auto-Boxing NullPointerException

What may one think to ones self, when a null pointer exception is thrown from a line of code as following:

MySpecialThing specialThing = new MySpecialThing (aLongArgument);

As if just to spite, the constructor is as harmless as:

MySpecialThing (long someNumber){ this.longNumber=someNumber;}

This is just one of those things that even an hours worth of code staring won’t resolve. The stack trace in this case gives no reasonable hint to what might be the problem. However, if its not obvious from the title, there is an auto-boxing of a Long object into a java primitive long.

The java compiler, wont see anything wrong, because such an assignment is perfectly legal, but at runtime if aLongArgument is delivered as null, the runtime exception is thrown from the constructor call(!).

Shameless.

Sunday, January 25, 2009

The bliss of code reuse

Almost two years ago, I wrote a java service for relaying and replicating some communication protocol for an American customer.

One of the requirements of that service was to have persistence for the protocol commands it was passing, so in case of a communication failure, it would repeat the signal over and over until it got through. The file persistence was to ensure that if the service itself crashed for some reason, it would be able to pick up on the same note without loosing a thing.

The design was fairly simple, an array of producer/consumer queues, each accommodating a two way communication path to a far away server.

Even though I had a very short time to develop and deploy this service, I was anal enough to make myself a very nice persisted queue implementation.

I used generics for the object that represents a single communication element. I used it naively by applying a string in the service I was writing, but I did see others use it in more elaborate fashions.

Because of some problems I had with using the Log4J implementation, I wrote my own logging mechanism. I did this since Log4J creates a drizzle of a memory leak when the implementation constantly adds categories and appenders at run-time. I figured that out while load testing, where I bombarded it with new sessions, I’ve notices that the log4J accumulated all the session appenders and never cleared them out. To smooth things out, I wrapped the logging implementation with a comfortable delegator, which allows an easy substitution; thus, my persisted queue was initiated either with log4J or by any other implementation (i.e. my own).

The way I made the persistence stick was to have a transaction like de-queue sequence. In lighter terms, what I mean is that once a message is de-queued by the consumer, it isn't removed from the queue and the persistence file, until a complimentary “commit de-queue” message is sent. I supplemented this with a regular de-queue method and a remove method that bypassed the FIFO mechanism all together.

I worked hard on making it as simple to use as i could. The base line initialization was without anything special, and was simple as calling a constructor without any arguments and would result in a simple blocking queue. That meant that nobody had to learn anything special about it, unless of course a special feature was actually required. The hard part is to overcome ones own bias to ones own code.

I’ve finally realized I’ve struck gold with this, one day when I was re-factoring some packages and notices that this module was being used all over the application.

I was mirthful and jolly

One of the reasons for my tipsy reaction was that while writing this little component, I did right and took the time to make a generic reusable module. It’s sometimes hard to tell while writing something new, whether it would ever be in use again. The academic approach of having everything reusable, is a fine methodology, but does have drawbacks when a customer is breathing down your throat, and doesn’t exactly appreciate paying for the reusability of the code.

Sometimes one just gets plain old lucky.

Tuesday, January 20, 2009

Is it a bug? Is it a plane? no.. its...

last night i found a very interesting bug while running the debugger in the flex builder (version 3)

I tries to compare an XML typed object to an empty string, don't ask me why.

the debugger was watching the expression (dataSource=="").
i then noticed that when the variable dataSource was not null, and actually contained a valid XML object; the debugger was evaluating a false result in the watcher while in the code, the result was opposite.

i caught a screen shot of this anomaly:

Sunday, January 18, 2009

The white rabbit: bugs and suggestions

current version : beta 0.2 (download)

this is what i have so far in terms of open bugs and suggestions:

unresolved bugs:
  1. project and task tree collapses whenever changed
  2. session time counter display: when changing back from monthly to session, the clock keeps showing the monthly accumulation

suggestions:
  1. "coast plus" configuration for the reports; suggested by Roy Reshef. have a configuration for adding a fixed overhead on the hour report, that would express the standard extra expenses. this is useful for freelancers that need to overload extra coasts on the hourly report. this might be implemented as a conversion to monitory terms as well.
  2. add a scheduler for tasks; suggested by Tomer Ben Arie. embed a scheduler into the project and task tree, that would allow time planning for implementation
  3. go large in enterprise mode; suggested by Ori Manor. enable networking and task legation from one user to another.
  4. oops mechanism, for backtracking in case i forget to stop the clock.
  5. floating task; enable time measurement without first determining the ownership. this is a nice feature when you are presented with a problem that you cant decide where to frame it until well into the task.
  6. task list view; a simple list like view where the user may thrown in "todo" tasks, and categorize them later.

Saturday, January 17, 2009

Follow the white rabbit




A couple of months ago, two things happened; one was that I got a project for a report wizard to do in flex. The other was the need to report on the hours I spent on it.

Learning Flex was a very nice and exciting experience. The need for precise accounting of time spent on this project made me start a side task on my little white rabbit.

The white rabbit is a simple, stand-alone application that measures time spend on each task in a project. It’s not fully automated, and relays the user to start and stop the clock.

Nevertheless, it does help keep organized and it does generate a report.

Why is it called “The white rabbit”? Because of the character from Luis Carol’s Alice in wonderland, the white rabbit fellow that runs around complaining about time or the absence of it.

So here it is. A simple tool, very easy to use, fully persisted standalone application.

The application was written using the adobe flex3 builder, and the package is installable in all windows versions and Mac OS, as long as you have flash installed (get adobe air).

The application has three aspects to it:

· The task management tool, defines a tree of accounts, projects and tasks

· The activity measurement tool, double click a task, and it starts counting the time

· And the reporting tool, temporal reports in a PDF format, ready for submission


Projects and Task tree management:

I have assembled the task tree with three entities:

· An account: represents a customer. A billed entity that would be receiving the report.

· A project: an assignment with a particular scope, one may regard this is as a directory of tasks.

· A task: a single work particle. Could be regarded as anything actually.

The only restriction I’ve set into this task tree structure is that the root of any tree has to be an account.

Figure 1: the porjects management screen

































The items in the tree, regardless of their type all have the following properties:

· A title

· A description

· Status (open or closed)

· An hour estimation

· An hour restriction (fixed price tasks)

· A deadline

Note: No field is mandatory; it’s up to the user to define the data regarded as useful.

Changing a task status (open to close and vice versa) changes its availability in the activity measurement tool. However, after closing a branch, it is still possible to generate a report on it.

The data is persisted as long as the branch is not removed from the task tree.



Timer, the activity measurements

This part of the application has a very simple concept.

The same task tree is displayed but filtered to show only the open tasks. If an element is closed, all elements on the branch underneath it are restricted from this view even if some of them are still open. This is for providing a way to shut down an entire branch without tediously closing each element by itself.

Once the desired task is visible, double click to start timer.

Figure 2: the timer, double click an element on the tree, and the clock stats ticking



















While working on a task, the application will not allow shifting to another task until an explicit stop command is set on the open session.

This is done easily enough by clicking the big stop session button in the middle of the screen.

I have a distinct dislike to having too many windows open all at once on y desktop. I would like to continue the time measurement on a task without having the white rabbit application open. So it is, that the application will continue counting up the seconds and minutes even if you close the application window.

The only way to stop the time measurement session is by explicitly clicking on the stop session button.

At this case, I open up the white rabbit, and click the stop button, the moment the timer screen appears back.

A friend suggested an ‘oops’ scenario, when I might forget to close a session while I’m off for lunch or something like that. I liked that very much and probably add that for the next release.



Reporting

The reporting aspect is the same task tree GUI viewed in previous aspects. The tree includes accounts projects and tasks, and by double clicking one of them, a dialogue appears, for setting the reports parameters.

Figure 3: the report creator, generates a PDF file according to a given template


































In this dialogue, the user selects the following:

· A report template

· May edit the report title

· Define time scope of the report by start and end dates

· Set the time aggregation for the report (resolution per session, day, month or just the bottom line)

· Set the task aggregation (either an aggregation of all the branch under the selected element, or a detailed account of each task by itself)

Once these points are set, the save button triggered the report generator and a PDF document will appear on the desktop.

Figure 4: a PDF report. Nothing fancy yet.














Installation, configuration, bugs and suggestions


The beta version of the white rabbit available free, on this link

Before starting anything, make sure that the system has an installation of the adobe air player.

Download the package, and double click it to trigger the installation sequence.

This application should install without any problems on any windows desktop platform or Mac.

When the application opens up the first time, the screen you will fist see is of the task tree.

Ease your way into the settings tab to set your personal data that would be eventually embedded into the reports to generate by the system. There is no need to do these configurations to be able to start measuring time on tasks. The minimal settings required are a single account and a single task under that.

Please feel free to pour your heard and suggest anything that comes into mind. That goes without saying to any bug you find.

To send me bug information or suggestions, you might find it useful to pop open the bug sending screen. To do that, click open the help (the question mark at the top right of any screen) and there choose the “report a bug” link button.

Figure 5: reporting a bug



















It’s a resent addition, and not fancy at all, only one attachment can be handled at a time, and there is no indication that the attachment is there (yet).

I would never mind reading how wonderful the application is and how useful you find it.

Have a jolly one.