Every project has its caveats but those that use DB2 have the omen!
Yes kids, it's rant time. Why do IBM must make developers lives through out the world so miserable? To the hell with bloated enterprise software.
After wasting time trying to figure out why Hibernate was having problems inserting blobs into DB2, our team realized the obviousness: blobs must have their size defined, no duh!
So imagine a domain object that reads:
@Entity
public class Image {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id
@Lob
private byte[] image;
}
To work in IBM/DB2 land it must read:
@Entity
public class Image {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id
@Lob @Column(length = 1000000)
private byte[] image;
}
And pray that your bytes don't get to big or you'll need to recompile your domain.
Wednesday, May 14, 2008
IBM - DB2 - Blobs - Hibernate - Truncating - Yikes!
Friday, February 8, 2008
True-blue Agile team
Yesterday was Iron Maiden's show. <scream> Maiden </scream> And I was there *grin*. Aside stating the obvious that it was an awesomely great show, they put me to think: why some bands, or groups of people more broadly, achieve success while the majority doesn't?
What’s the recipe? Is it talent? Is it the hard work? Is it never giving up? All of the motivational aspects are probably there, but I'd say that the common ground is that, most invariably, great teams didn’t start off great. They learned how to be great together. Team learning is key to a team’s success. Individuals have their unique capabilities and may even be the best in their fields, but unless they learn how to play together nothing really happens.
A true-blue Agile team-player knows that the team comes before the individual. As Mike Cohn says: “…the team must precede the roles”. “I’m in project XZY as a developer.” is very different than “I’m a developer assigned to project XZY”.
Another import aspect is that the sense of accomplishment has to be shared. If one person tries to take credit for the success or play the blame game when things go wrong, then that person isn’t a team-player.
As lastly non team-players must leave. Those who don’t want to learn how to be a team should go away. Keeping around people who cannot orchestrate their actions and thoughts will take toll on the whole team. But don't feel bad about it there will always be enough space for those who like to work in solitude not sharing their sufferings or findings.
OK, so it’s all about creating a synchronized learning team, but how do we achieve that? There are many lines of thought on learning organizations, IMO Peter Senge is a great reference, but is it enough to create a first class Agile team? Are Agile teams learning teams? And finally, can we apply Agile techniques to help teams become Agile? What do you think?
Tuesday, January 29, 2008
Technical Debt is a cancer
After a discussion about Technical Debt (aka TDebt) in Thoughtworks I realized something: Technical Debt is just like cancer.
There are several similarities between the disease and this "condition" that happens quite frequently in development projects.
There is a line in medicine that says that if you live long enough you will develop some sort of cancer because organisms have intrinsic failures that will manifest themselves if enough time is given. An IT project that lives long enough will present TDebt related problems.
Cancer can develop from external factors or congenital predispositions. Tobacco, sunlight or too much tuna can disturb your organism to a point of metastasis. Less than good design/coding decisions affect the general project’s health in similar way. If the team chooses to cut corners and develop bad code intentionally TDebt will build up. As for the congenital problems that may be circumvented by using some tools. From a Java angle it can be FindBug or PMD to continuously inspect congenital problems related to the technology stack of choice.
No one wants to discover a cancer but once you find it you need to take some action or it can have terrible effects. Tackling TDebt is hard and many choose to put it off until it's too late. However if the case is a terminal one, then nothing can be done. All you can hope for is for it to live long enough to fulfill its purpose. Different types of problems require different procedures. But seems that the most popular and successful approach is: isolate and remove.
Early detection and prevention are key. The sooner the problem is identified the easier it is to heal. Regular check-ups are a Good Idea™. If a potential problem is detected it should be examined to determine whether it is benign or malign. After that one can decide the course of action. Also there's no point in being a hypochondriac, this shouldn’t consume the team’s time away, it’s preventive not obsessive.
Some people get worse after they discover a cancer because their moral gets shot. Projects slow down because of TDebt, which gets devs very de-motivated. TDebt makes things unnecessarily complex turning simple tasks into major efforts. Anything that impairs people from living normal lives have devastating effects on their will.
Sunday, January 27, 2008
HashMap temptation
When integrating systems it is very easy to fall into HashMap temptation. “Just put some details in a Map and pass it to the service layer and it gives back what you need”. Maybe,… but there are risks.
I consider passing Maps around to services an anti-pattern because interfaces become less intentful and creates coupling between layers.
Let’s consider a hypothetical example of a farm system. Every morning old McDonald wants to name roll call all animals to ensure they are safe and sound. Farmer McDonald knows he has animals in the pond and on the pasture.
On the first pass we create a service receiving a context Map, keyed by environment type and containing animals’ names. The service returns a List with farm Animal instances.
Old McDonald knows the animals’ names, where they live and expects them to say: “present”, in their own dialect, obviously. One client program could look like the one bellow:
With this implementation it’s impossible to have a pond roll call only. But that’s not the worst thing, knowing that the service needs to be aware of different environments and keep track of them is the creepiest part. One solution is to make the service layer more intentful and have old McDonald say explicitly the animals of which environment he is roll calling:
Now instead of a Map it’s a List that gets passed around, the service interface expresses *exactly* what’s to be done and code can be re-used. The downside is that an extra call needs to be made from the client. In this particular example it’s not a major hassle because it requires no extra information about the livestock:
Bottom line: avoid passing Maps around and put more effort into defining highly intentful interfaces. As a rule of thumb service layers are dumb, hence they don’t have to decide which method/logic is to be invoked based on states/keys of other objects. Service layers should only know about domain objects and which methods to invoke. Utilising HashMaps in similar ways to this example violates the Tell, Don’t Ask principle. This design forces service layers to understand what’s inside of Maps to decide which method to invoke and the client layer in its turn, must create Maps with all things the service needs in order to process the call, which smells like coupling.
Friday, January 25, 2008
Why Agile adoption fails?
Why some seem to succeed to produce quality software using lean methodologies and others don’t?
For starters there’s a giant lacuna between acknowledging that Agile is useful, fast, high quality, etc and been truly Agile. For Agile to work one must believe and *act* according to her beliefs!
I’ve noticed that teams fail to create software using lean approaches mainly because of their preconceived mindsets towards an apparently less predictable, although more precise, model.
Unfortunately no one can build software as if it was a house. In software construction you *can* have your own voltage, no gravity and wine instead of water running in the pipes. Therefore managers need to accept that will this level of freedom there is a proportional level of uncertainty that cannot be cleared upfront, regardless of the effort put into planning and estimating.
A forcefully preset release date on a spreadsheet means very little to software development. In the outset it only expresses a desire. Functionalities need to be sized, time must be derived for sizing and then, only then, a date estimated. Even after that, realize that that’s all it is, an estimated date.
Trying to re-estimate stories because they’re taking longer than expected is another contributing factor for disaster. Let velocity do the work of defining progress, story size cannot change speed.
Teams have a hard time accepting that there’s only so much that can be done to go faster in order to meet a deadline. Reducing complexity is one option, re-prioritizing and re-scoping too. Resizing your team can also have positive impact, but overtime not. By working long hours quality will inevitably be compromised and reducing quality is not an option in Agile.
Some say Agile is too informal, and even that it makes the office space look ugly with all of those cards on the walls! Software development has always been messy and Agile only exposes it so people can act upon it. Agile is formal, as formal as the organization using it wants it to be. And yes, there is planning too. I don’t have figures but with Agile there’s more planning effort than waterfall. The difference is that the planning is diluted in everyday work such as stand ups, technical huddles, iteration planning meetings, kick-offs, planning poker, etc..
Agile is highly dependent on talented developers. Roles such as team managers and architects have less or no impact in Agile teams. Traditional waterfall micro-management kills creativity and architects tend to do a lot of upfront design and create unacceptable resistance to design change over the course of stories. The devs need to be different too. Agile devs must be design savvy, have creativity and initiative.
Lastly, if all of this seems too daunting and you don’t want to take the risk of figuring out Agile heuristically, go and hire an Agile consultancy. Get people with experience to help you out in a few projects and inculcate the principles. This way the organization gains confidence, establishes a faster return of investment and creates enough in-house Agile champions to sustain the changing momentum throughout the company.
Sunday, January 20, 2008
Swing Acceptance Testing with JFC
After many years developing for the Web I found myself having to do some Swing code and *obviously* had to do some testing for it. I went with JFC for the functional tests and here’s a little cookbook.
The test class extends from JFCTestCase public class CurCalcTest extends JFCTestCase
The main JFC class to take heed is JFCTestHelper. Probably a Good Idea is to set it in the setup method:
protected void setUp() throws Exception {
super.setUp();
setHelper(new JFCTestHelper());
}
After that, my approach was to get the container under test/investigation:
JPanel curCalcPanel = (JPanel) frame.getContentPane().getComponent(0);
And then obtain each one of the elements I want to manipulate, such as comboBoxes, textFields, and etc.:
NamedComponentFinder amountFinder = new NamedComponentFinder(
JTextField.class, "jTextFieldAmount");
amountField = (JTextField) amountFinder.find(curCalcPanel, 0);
NamedComponentFinder countryComboFinder = new
NamedComponentFinder(JComboBox.class, "jComboBoxCountry1");
countryCombo = (JComboBox) countryComboFinder.find(curCalcPanel, 0);
NamedComponentFinder messagesFinder = new
NamedComponentFinder(JLabel.class, "messages");
messagesLabel = (JLabel) messagesFinder.find(curCalcPanel, 0);
Now I can insert my keystrokes/clicks using the helper:
getHelper().sendString(new StringEventData(this, amountField, "1"));
getHelper().enterClickAndLeave(new JComboBoxMouseEventData(this,
countryCombo, 1, 1));
getHelper().enterClickAndLeave(new MouseEventData(this, convertButton));
And assert my expectation(s):
Assert.assertEquals("0.97478773", messagesLabel.getText());
JFC is another fantastic tool by ThoughtWorks. It is a very useful framework but not friendly all of the time. For instance, if you forget to identify the elements properly via the setName() method, and try to use NamedComponentFinder no error is given, the thread just sits in there without complaining about anything.
Saturday, January 5, 2008
New Year's resolution

Is it too late for a New Year resolution?? Probably not. Then here it goes. I'll learn Ruby in 2008. These are the reasons:
- I'm getting a bit tired of Java and Ruby seems to be the next logical move
- Now that JRuby is out, chances are that the Ruby will really make to corporate environments
- It has a strong community
- ThoughtWorks is supporting it wholeheartedly, BTW welcome to the team Ola Bini!
- Ruby is very flexible allowing some very fancy things, still lacks a bit of control thou
- Finally and most important, Ruby is Agile