Posts

Showing posts from 2012

Ubuntu 12.04 on macbook pro

I'm a long time linux user, I installed my first distro in 1994, it was slackware and required a bunch of floppies and was a fairly painful process. Over the years, I migrated from slackware to redhat and finally settled on Ubuntu as my "daily driver". Every computer in our house (a server, three laptops, and two netbooks) is currently funning a flavor of Ubuntu and I decided to give setting up my work machine (macbook pro) with Ubuntu. The big reason I like Ubuntu is that they are doing a good job of making an operating system (OS) that finds a great balance between "you can do anything you want" and "I just want it to work". Ubuntu has thousands of free software packages that are tested and verified to work that will install with the click of a button. Windows and OSX are so far behind in this regard as to not even be contenders. While there is a little more technical knowledge necessary to get Ubuntu up and running, it typically has so many r

Developer's Creed

So borrowing an idea from the NCO Creed , I thought I do one for software developers: D iscipline will be my watchword, the software I create will never be perfect, but I will perform my job to the best of my abilities and remember that every letter I type should have purpose. E go is the enemy of good code, I will remember that "I am not my code" and never fail to admit mistakes and fix in in a humble manner. V alue is provided not through MORE code, but less. My software will be succinct. E nergy overshadows ability, I will bring my "A" game and not give up because it's "too hard". L ove for my users is always in my heart, they will break my code, I will fix it O penness wins over closedness, I will share my tips and secrets and together we'll all make the world a better place. P atience is paramount, sometimes the answer isn't the first, second, or fiftieth idea. E mpathy for the newbie and the uninformed wins, you never know when t

Effectively communicating software requirements - PART 1

The most important factor that contributes to a successful software project is ensuring that the development staff has a good understanding of the requirements. Incorrect requirements almost guarantee incorrect software behavior. Most often, however, the requirements aren't clearly incorrect, but rather they are vague, ambiguous, or make incorrect assumptions about the best way to apply technology to solve the problem. The original title of this post was "Writing Good Software Requirements", but I realized after writing the previous paragraph (irony noted) that writing good requirements is actually part of the problem. Having written software my entire adult life and much of my childhood, I've been most effective writing software for myself. This software has always done exactly what it was supposed to do (technical bugs notwithstanding) and the reason is because I had a visceral and complete understanding of the problem I was trying to solve and what factors

equals and hashCode for dummies (again)

In java, writing equals and hashcode methods are perennial problems. Newbies and experts alike are confounded when things go haywire and troubleshooting problems can be extremely difficult. A common thing that a poor hashcode/equals implementation will cause are intermittent problems and/or mysterious out of memory errors. To help clear things up, I'll give a 10,000 overview of how the core java libraries use the hashcode/equals methods. Essentially, the hashcode/equals methods are used when storing things in Hashes (HashMap, Hashtable, HashSet). Things often go wrong when folks start using custom objects as keys for these classes. For example, let's say we have a person class that looks something like this: public class Person { public Person(String orgName) { this.name = orgName } private String name; public String getName() {

Fixing Hibernate, DB2, H2, and Boolean Issues With a User Type

Edit: It was pointed out that this was a problem with H2, NOT Derby... not sure how I missed that, I've updated (Thanks Nick) Our team recently started using H2 for local development, with our production database being DB2. One nice thing is that the sql dialects for these are nearly identical and you don't need to change the dialect to get things to mostly work. We did, however, hit a snag with our boolean type fields. By default, the values for a boolean object default to "1" and "0" (or 1 and 0) when using the db2 driver and definition the column as a char(1), but when using the h2 jdbc driver (with the DB2 hibernate dialect), the values were getting translated to "true" and "false" which was breaking because obviouly you cannot store 4 characters in a 1 character field. After googling the problem, it turns out a lot of people have run into this and there aren't any obvious solutions float

How to juice your java performance

Warning: This is a preoptimization In my previous post about equals and hashcode I thought I'd point out how to redesign the class in question to make better use of performance. If you have a situation where you create groups of objects that are immutable, but you need to pass them around in hashsets and/or look things up, a way to increase performance is to change from something like the following: package blog.mainguy; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; public class LookupEntity { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public boolean equals(Object other) { if (other != null && other instanceof LookupEntity) { return new EqualsBuilder().append(this.getName(), ((LookupEntity) other).getName()).isEquals(); } else { return

Use computers for repeatable tasks, use humans for creative tasks

Pundits often refer to the notion that the most effective developers are 10 or more times as efficient as the least effective. I think this is probably an understatement, but I think the reason is often oversimplified. Many of the "more effective" developers seem like to pat themselves on the back and chalk it up to being smarter or some other nonsense. While arguably this is true, I think it is more that the most effective developers HATE doing the same thing twice. I think this is an important detail because computers are REALLY good at doing the EXACT same thing millions of times per second. People are not very good at this... in fact it's arguable that it is impossible to do the same thing exactly the same twice in a row. The truly effective developers are the ones who use computers to do the repeatable tasks and use their unique human curiosity and creativity to find new things for the computers to do. More importantly, the best software development shops r

How to shoot yourself in the foot with HashCodeBuilder

The setup HashCodeBuilder is a nice tool provided in apache commons to help building infamously difficult hashCode and equals methods in java classes that work properly. While I appreciate the tool, versions prior to 2.5 had a subtle api design flaw that is likely to bite you if you aren't careful. To illustrate how subtle the design flaw is, take a look at the following code: package blog.mainguy; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; public class LookupEntity { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public boolean equals(Object other) { if (other != null && other instanceof LookupEntity) { return new EqualsBuilder().append(this.getName(), ((LookupEntity) other).getName()).isEquals(); } else { return false; }

Clean code is an important quality, but not the MOST important

Clean code is a book by Uncle Bob Martin that speaks to principles in software development that lead to high quality, legible software. This is a great book and every developer should read it once (or twice). The book outlines important tools and techniques, but these are not the end, they are a means. I've noticed a lot of folks treat clean code as the "secret sauce" that makes great software. Unfortunately, they take it a little too far and by being too focused on their secret sauce, they forget that it's worthless if the customer starves to death waiting for the secret sauce to be "perfect". At one point early in the book, Uncle Bob uses the metaphor of physicians and hand washing. In particular, he makes a point that it would be unrofessional and possibly illegal for physician to not wash his hands before surgery, even if the patient (the customer) asked for it. I like this metaphor and I think he makes

Java programmers: Code to the interface, even if the interface is a class

After spending a considerable amount of time trying to figure out how to refactor some particularly hairly (hairy + gnarly) data access code, I thought I'd share some insight into a popular misconception about what coding to the interface actually means. Let's say we're writing a data access layer and we have something called the UserDAO. a simple implementation might be something like: public class User { public int id; public String name; } public class UserDao { public boolean save(User toBeSaved) { } } I'm going to dodge the issue of the user class not having getters and setters and thus not following the javabean spec and talk about the UserDao Interface. Yes, you heard me, the UserDao class effectively is an interface in this example. Sit down and just think about that for a minute, once you've done that, move to the next paragraph. A great (GREAT) many java developers might not get to this paragraph because they'll imme

ya ain't gonna need it until ya need it

Yesterday I posted a somewhat snarky comment about how You don't need layers until you need them which may have seemed like a nonsensical thing to say. Today I was started to write an example of how to refactor an anemic data model with lots'a layers into a lean and mean persistance machine... but stumbled into a perfect example of what I was trying to say. In essense, I was trying to repeat the idea that "Ya Ain't Gonna Need It" , but with emphasis on the fact that... Yes, you may KNOW you're going to eventually need it, but building infrastructure before you need it accumulates overhead that you must pay for, even if you don't get the benefit. My Example (Snippet of pom file) <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 htt

All java archeditects read this

I have a couple of quick notes for any aspiring java architects. Please read them carefully and think about them. Adding layers is BAD In general, you don't need extra layers until you need them. At that point, add a new layer (but only in necessary places). Create "standard" layers just adds complexity, makes maintenance more expensive, and ultimately fosters copy/paste coding and discourages developers from thinking about what they're doing. An example of a good time to add a layer is when you need to hide complicated operations behind a facade because low level database transaction management is being done in the same place as the code that determines which screen should be displayed next. Too many developers heard "layers add flexibility/scaleability/whatever" and started adding layers to every situation that has an arbitrary division of responsibility... I've worked on systems where adding a table column to be displayed in a CRUD applicatio

The Notoriously Tricky "Step 0"

I recently posted about " Git for Dummies " and noticed that commented that they had followed my instructions and had a strange permission issue. Wanting to verify everything was correct, I did a quick check and, sure enough I was having the same problem. Upon investigation, I discovered that I had posted a which required a public/private key pair and folks who hadn't already set this up on their machines would get an error. The post was supposed to have been written for a new user and they typically wouldn't have done this. As a long time github user, I did this one time setup ages ago and had totally forgotten about it. This is common occurrence, so common, that I give it a name... I call it "Step 0". This is a variation of the curse of (prior) knowledge and can be frustrating for both people trying to learn something new as well as people who are trying to explain how to that something to a newbie. In essence, "Step 0" is the prior knowl

Exploiting the Cloud for Personal Productivity

I'm currently doing an evaluation of Drools to illustrate the differences and similarities between it and JRules. Due to time constraints, most of this is being done on a train commuting between Chicago and my home. This means I'm doing most of my work at 60mph over a 3g connection. This also means that my network is constantly dropping, slowing down, and otherwise misbehaving. So to evaluate drools, I needed to download the 300ish mb zip file and set up. Originally I started downloading to my laptop but realized this was just going to take longer than I really wanted. So, I fired up an ubuntu EC2 AMI, typed "wget http://download.jboss.org/drools/release/5.3.0.Final/guvnor-distribution-5.3.0.Final.zip" and was ready to roll in 5 minutes. An additional benefit to this is that I can point people to the ip address of the EC2 instance and they can actually start to use the product without requiring me or my laptop to be present. An even bigger benefit is that

Always Pull Branches When Merging

A question came up at work today that I've had to stop and remind myself numerous times and I'm sure other people have to think about on occasion. When merging changes from a branch back to an origin, should I pull them from branch into origin or push them from branch to origin. The difference in CVS would be... do I check out the origin and merge the deltas of the branch into working copy or check out the branch and somehow push those changes onto the trunk. In short, always pull changes into a clean local copy that represents where the destination of the merge should be . It really doesn't matter which Revision Control System you use, this will almost always be the safest way to merge (assuming it supports a local copy). I say this for one very important reason, you MUST be able to resolve conflicts before committing changes to the central repository, pushing doesn't necessarily allow you to do that unless the tools supports something like Multi Version Concu

Confessions of a Morning Person

Hello, my name is Mike and I'm a Morning Person. During a brief stop at the gas station this morning, I said hello to another guy entering the gas station as I was leaving. Not sure what he was doing up at that hour, but the serene look on his face was a perfect reflection of how I was feeling. As a person who routinely wakes up at 4-4:30 am, I love the morning. Don't get me long, I like to sleep... and need about 8 hours to feel rested, but I would rather go to bed early to not miss the morning than stay up late and sleep in until until 8:00am. On my drive to the train station, I started to explore what I liked and a variety of memories sprang to mind: As a young child, waking up 30 minutes early with my brother to get dressed, then get back into bed so that when Mom and Dad came to wake us up, we were already prepared (occasionally sneaking out to get breakfast too). Relishing the look of surprise when they realized we were ready to go. Waking up as a teenager, m

Lotus Notes, A Lesson in Poor User Experience

Image
As a longtime Outlook user, I've had the exciting experience of learning how to use Lotus Notes. When first starting to use it I was shocked at how "clunky" the user interface seemed, but wrote it off as my long familiarity with outlook. Recently, however, I started to realize that I was being too generous. Notes is full of user experience bad enough that I feel I need to point a couple out lest any young engineers try to design user interfaces based on them. These things are actually a combination of how Notes works as well as pretty poor administration of the tool. There are some settings which, when you log out of a tool, your personal preferences are reset, but others where they are saved. As two quick examples, I give you the following: Yes,No,Cancel By default, when sending email, Notes prompts with the following dialog: By itself, it is not a HUGE problem, we're not only giving you the option to save or not save in "sent items", but

The VB Model versus the Delphi Model

As an older school client/server developer, I've used by VB and Delphi for a few projects in the past. Having seen both tools, they have a difference of approach that I think is significant. The VB model is "90% of what you want to do is easy and the remaining 10% is impossible" whereas the Delphi model is "80% of what you want to do is easy and the remaining 20% is more difficult". In the VB model, because it was such a closed ecosystem, when I couldn't do something, I'd have to go buy components from a third party or write a C library. There were multiple times when using VB I needed to write a special component in C or Delphi because VB just couldn't handle it. In addition, I was often forced to purchase third party components because nothing was available in the open source space. In the Delphi model, with it's richer open source ecosystem, when I couldn't do something, I'd first look and see if there was an open source compo

Disruptive changes fuel innovation, innovation creates disruptive changes

As a developer who works extensively both ruby and java, I'm amazed at the turmoil in the ruby/rails space relative to java.  In the last few years, ruby and rails have had numerous massively headache inspiring incompatible changes that cause developers who used to know what they're doing to realize they're doing it the "old fashioned" way. A particularly entertaining example from recent history is the handling of scopes in active record.  Not only has this changed from Rails 2.x to Rails 3.0, it's getting further changed in Rails 3.1 (in an incompatible way). I will agree that these are good changes, but they are certainly an effect of not spending time to think things through the first time and cause problems for newbies and old hats alike. Compared with java  based projects (anyone still remember moving from hibernate 2.x to hibernate 3.0?) this rate of change is mind numbing and can be pretty frustrating. But, compared with the amount of innovation

Being too early devalues your time

Arriving at every event too early, is a waste of time. If it normally takes 15 minutes to drive somewhere, some people will leave 30-45 minutes early. As another example, I meet people who arrive at the train station for 15-20 minutes before the train arrives almost every day for no good apparent reason. My personal opinion on this is that showing up at the appointed time is optimal. Doing simple math can show that showing up early devalues your time. For this simple example, let's suppose I get paid $10 per hour to do a job. If I agree to work 1 hour per day at this rate, but I show up at work 15 minutes early every day, my hourly rate just dropped from $10/hr to $8/hr. My agreement with my boss was to work 5 hours and receive $50 dollars, this amounts to an hourly rate of $10 per hour. What I actually DID, however, was donate an extra 1.25 hours (15 minutes per day over 5 days). I will point out that the word "unnecessarily" is key because depending on t

Why some people think messaging is more scaleable

I've often been around (or in the middle) of debates about how message oriented middleware is more scaleable than web services. The problem with this debate is that it is a false dichotomy. There is no reason you cannot do asynchronous http services where the response is simply "Yep, I got it". In practice, these services are just as scaleable and flexible as their queue based brothers and typically are not nearly as complex. Some of the reason this propaganda gets started is that non-technical folks need to be told a reason why a particular technology is more appropriate. Folks will often use "hot button" phrases like "it's more scaleable" instead of trying to actually explain in nitty gritty detail what the real reason is. Additionally, making asynchronous web services is truly a bit more challenging. The APIs for JMS foster the notion that the message is transmitted and immediately returns. HTTP libraries typically espouse the idea

Run your enterprise like a startup

I've worked in a variety of companies and I notice an interesting phenomena -- It seems that the capabilities of individual programmers in companies are inversely purportional to the size on the company. Tech startups with 3 folks always seem to have superstars, even though it's a huge drain on their budget, but IT shops with 1000 people seem to always have 10 people who seem to be doing everything. The irony in this situation is that a startup has the least amount of money to spend on programmers, but requires hiring only the best and needs to spend a disproportionate amount on payroll. On the other hand, a company flush with cash that could easily hire only the best and brightest, inevitably hires "everybody else". This means that particularly large shops end up with a handful of superstars (just by sheer luck of the draw) who do the majority of the work (and then burnout and leave) and a bunch of "also ran" folks who are really just padding their re

Aggressive control freaks make great programmers

After reading Give it five minutes I saw an interesting pattern. Of the folks I know, the good/great programmers are all pretty aggressive. In addition they are also pretty controlling. Moreover, when reading the comments to this blog post, I was struck by the number of folks who could identify with the "hothead". As a person who historically fit in to that personality type, I wonder why this is. It seems to me that the reason has to do with the way people interact with computers when programming. The very idea of being 'in charge' of the computer and making it do anything you want would seem to appeal to this sort of personality. In addition, the current market and the rate of change handsomely rewards people who aggressively pursue this end. Very successful programmers are the ones who can do this most effectively. The obvious downside is that this creates a situation where negative behaviour (in human interaction) is actually rewarded. Without conscio

Using Mongoid, MongoHQ, and Heroku

I recently tried to set up mongoid with a free mongohq account on heroku... This info is accurate as of 28 Feb, 2012. For the impatient (I just want to make it work) mongoid.yml production: uri: <%= ENV['MONGOLAB_URI'] %> Gemfile gem 'bson', '1.3.1' gem 'bson_ext', '1.3.1' gem 'mongoid', '2.0.2' For those who want more detail (I have a similar problem, how do I troubleshoot To determine heroku environment variables, do this: $ heroku config and the results should contain a line like what follows: ... MONGOLAB_URI => mongodb://heroku_app928349384:lkfjgoierheourhgoeurhgoeuh@ds031087.mongolab.com:31087/heroku_appapp928349384 ... The important thing to note is what the left hand line says. Around the internet (like here on SO they will incorrectly name the ENV as MONGOHQ_URI. So then update mongoid.yml like this: Additionally, it appears that different versions

Governance Gone Wild

I've written in the past about change control processes and how they relate to agility. Taking things to the next level, there's a bigger issue that needs to be addressed. There are essentially two radically divided camps on what value IT Governance provides for enterprise software. These camps are: #1 the business camp which is tired of hearing excuses about why they are losing millions of dollars of business because IT cannot deliver a solution in a timely manner and #2 The IT camp that is tired of the business camp requesting crazy stuff and causing millions of dollars of unnecessary support costs. Camp #1 thinks governance is an excuse for IT/process wonks to slow things down or foot drag instead of delivering solutions. Camp #2 thinks governance is a way to reign in the business folks who believe that unicorns and pixie dust cause fully configured computers and network infrastructure to magically appear over night. I hope its obvious that both camps are spectacula

Architectural Antipattern: "Through The Looking Glass"

An anti-pattern is a commonly occurring pattern that is ineffective. There is an architectural anti-pattern I like to call "Through the Looking Glass". This is when a system is broken into pieces or layers, but the pieces are cut perpendicular to the direction that the team and the business require. A common example is when a set of screens used to access a database system is split system into "front end" and "back end" components. This "front end" and "back end" split ONLY makes sense if the back end can identify thier required interfaces before the front end is designed. If the "back end" requirements are being driven by the "front end" screens and/or systems, then this split is either #1 wrong or, at a minimum #2 premature. Most often, new systems need a front end to identify APIs that need to be used... it's more economical to build the system in such a ma

The Best Practices Myth

I've found the term "best practices" to typically be a magical incantation that people invoke to use a fictitious third party expert to support their position. When most people say "best practices dictate" they're really just saying "because I said so" and I meet them with extreme skepticism. This is not to say that the idea of "best practices" isn't alluring. Wouldn't it be great if we could simply do things the "best" way and not have to think about what we're doing. In fact, sometimes it might be valid, for example a "best practice" in java is to follow a naming convention. The first letter of classes should be upper case for example. I think this is reasonable, but frankly I'm currently hard pressed to understand WHY. If you're going to recommend best practices, I feel you have an obligation to be able to explain the NEED of the "best practic

people are not interchangeable cogs, they are more like the wind

Great organisations understand that people are not interchangeable cogs, but the wind in their sails. I've struggled to come up with a metaphor that helps explain why command and control processes are so failure prone. In a command and control process, someone (or worse yet a committee) decides "how we're going to do things" and then builds a process to support this idea. Truly degenerate cases will take a step further and try to buy tools and then build their process around their tools. These struggling organisations then spend years try to find the right people or mold people to fit into their process. These organisations have fallen into the trap of thinking that people are just pieces of a giant machine and that once they state their process, they simply need to find the correct pieces and hook them together. The problem wi