May 21

A few weeks ago I came across a piece of code inside a DAO class with logic to instantiate new model objects and return them with null contents (new object) instead of just null itself. This is wrong. It is particularly wrong because the entire rest of the DAO classes in this application use the normal method of just returning whatever hibernate does, IE, null if not found. layer separation is important. Please keep such logic out of the DAOs and put it where it belongs above. Doing this precluded using the same DAO for other purposes without changes in several classes - yuck, spaghetti.

Another gem I found with the same author was a class with about 7 methods, one public, the rest private. The public one had an if else structure which delegated to the other methods. The return type was boolean. Upon inspecting these methods to see what they did and why true or false might be returned, I came across the following :

boolean ret = false;
// Lots of code, some of which throw exceptions...
ret = true;
return ret;

Which can of course quickly be refactored to :

// Lots of code, some of which throw exceptions...
return true;

Which in turn can quicly be refactored into :

// Lots of code, some of which throw exceptions...

But, of course, with a return type of void, NOT boolean.

As it turns out, there was some reasoning to this exceedingly dodgy code. The boolean, urr, i mean, the true value (or exceptions) were being processed and converted into serialised JSON for a front end display tool. I still would not have done this, rather I would have used a return type and embedded the exception, message, and true/false value in that directly (such a return object already existed). If you were going to do this, comments were essential… there were none. Poor form.

Lastly, again, from the same author, we have the following method signature :

Employee getEmployee(String email, Integer offset) {

Which, at first, seems reasonable enough. On closer inspection it was apparent that it actually had a few side effects. What it really did was this :

Employee employee = employeeDAO.findByEmail(email);
if (employee.getEmailAddress() == null) {
    employee.setEmailAddress(email);
    employee.setLanguage(languageBO.getLanguage());
} else {
    languageBO.setLanguage(employee.getLanguage());
}
labelTextBO.setLanguage(employee.getLanguage());
session.setRequestedFor(employee);
session.setSubmittedBy(employee);
session.setTimeZoneOffset((offset != null) ? offset : 0);
session.setLastLogin(employee.getLastLogin());
getEmployeeDetailsFromLDAP(employee);
return employee;

So, of course, I changed the method name to this such that any potential user could instantly tell what it was going to do for them…

Employee getEmployeeAndPopulateSessionAsSideEffect(String email, Integer offset) {

Again, this is the sort of code that leads to mistakes by unsuspecting developers that come along later and wonder why it behaves so stangely, afterall, all they did was get an employee, right?

The astute among you will, by now, have noticed that the DAO which returned the fresh object instead of null was the EmployeeDAOImpl class as used in the EmployeeBOImpl. This project was, unfortunately, riddled with such messy dangerous code. We’ll leave the class and method naming for another day as that was appalling in places too.

It would appear that the colour scheme for Java doesn’t go at all well with my theme’s style. I’ll try to remedy this shortly if possible.

Apr 7

This really belongs on The Daily WTF, but it will just have to live here for now I guess. All real names (except mine) have been replaced!

Preface :

A few months back I setup a project using Maven2 from scratch (You’ll hear more about this in an upcoming article). This project wasn’t large, but had strong potential to require a mildly complex build setup for multiple clients.

For those unfamiliar with this indispensable build tool, one of its major positive aspects is that dependencies on other artifacts are explicitly declared by the developer based on his understanding of the projects environment. Another is consistency - that you can ALWAYS sit down and “just build it” on a maven project with absolutely no knowledge of the specifics. There are many more.

I was stolen from this project a month or so back and moved to a new one. This project is not popular with the resourcing department of the company it is being produced by so staff theft (to other clients/projects) was commonplace. As of yesterday the project has one front end flex developer who knows that aspect very well, and one new java back end developer who doesn’t know much about it at all.

Body :

Over the last few days since the new guy started on my old project I’ve been contacted fairly regularly with various questions about how to find this, what the password is for that, etc. Today the back end developer contacted me asking for help with doing a release of the system. His Maven knowledge was a bit thin so it should have been a 5 minute case of “type this and hit enter” type stuff. Not so fast, Fred.

Something is wrong with this pom.xml snippet :

<groupId>com.company.application</groupId>
<artifactId>services</artifactId>
<version>${this.version}</version>

These instructions might start to explain why :

7) Run ‘mvn company:version’
8) Run ‘mvn scm:checkin –Dinclude=pom.xml –Dmessage=”company:version”
9) Check pom.xml and ensure the version element contains ‘${this.version}’ and the this.version element (child of the properties tag) contains the newly incremented snapshot release version number, e.g. 0.0.4-SNAPSHOT 10) Check the subversion history, it should appear something like this:

3346       31/03/2009 10:34              1              user       company:version
3345       31/03/2009 10:00              1              user       [maven-release-plugin] prepare for next development iteration
3343       31/03/2009 10:00              1              user       [maven-release-plugin] prepare release xxx

The somewhat edited conversation in which I found out about these changes (expletives removed) :

Fred: did you release those artifacts?
Bob: Partially, Harry did but forgot to do the mvn company:version command so Henry did that
Fred: wtf is that?
Bob: It updates the version numbers in the pom
Fred: it does what?
Fred: who put that in?

A small snippet of conversation after pasting the above to a colleague :

David: omg lol, they actually bothered to write their own plugin to circumvent maven versioning
Fred: Yes…

It turns out that another developer had put a significant amount of time and effort into creating a plugin and configuration to automatically update dependency and artifact versions. This allows them to work on multiple packages in parallel to produce a working product at the end.

Summary :

So, what is the big deal? Well, for starters, dependency versions should be explicitly set. Why? Because you and ONLY you know what is required. Who says that the latest data access library is the one you really want to use? Automation of this task is plain just a bad idea. Secondly, the project is no longer a normal standard Maven2 project. As such it is difficult to support it remotely without having a good look over the “plugin” and other associated changes. In short, several of best Maven’s features have effectively been disabled and made worthless by these senseless changes. But, the developer must have had a reason for doing this, right? Yes, laziness and lack of up front component and interface design. These features allow an application to be thrown together haphazardly with little thought in a fine grained incremental development style described as Programming by Coincidence. Such practices are best avoided especially by inexperienced developers, using a properly modularised project layout goes a long way to fostering a good working style.

On another, more positive, note :

Lastly, the formatting on this page was done with the following WP-Syntax plugin. The style sheet for the code blocks still needs some work, but I’ll get there sooner or later.

Update! (14/4/09)

This evening I had the pleasure of being asked (ever so nicely) to come back into the office after hours to help get a build of the project out. After getting a normal mouse connected and a usb keyboard (ps2 seemed to die) I started fishing to see what was wrong. Of course it was just a matter of adjusting some versions to match (I had [] hard versions setup to guarantee consistency). No problem there. The usual array of error messages were being pumped out. No problem there. The problem (and it was only a small one) turned out to be that the carefully used variables for versions of dependencies had been replaced (presumably by the script/”plugin”) with hard coded versions. Thus editing the variable at the top made no difference at all as it wasn’t being used. I guess it’s possible that the developer was to blame, but I strongly suspect it was the “plugin” working its magic and screwing things up. Certainly the developer was surprised to see the hard coded versions in place. Lesson learned? We will see what happens as time progresses…