Monday, November 21, 2011

Startup without falldown: the slides

Here are the slides of my talk "Startup without falldown: strategic planning beyond wishful thinking", held at the 8th Italian Agile Day in Rome:
I'd like to thank everyone who has attended, I hope I haven't wasted their time. If you are one of the lucky (???) ones, please help me to improve and leave a feedback here.

If you want an exhaustive bibliography please register here and you'll receive it in a few days, with a bonus mind map of the talk.

Monday, October 24, 2011

Goodbye Sic

Wednesday, October 19, 2011

Startup without falldown: strategic planning beyond wishful thinking

The official program for the 8th Italian Agile Day has been officially published. I am really happy (and a bit surprised) to see that my talk has made it to the final 26: I am sure that many of the talks that were left out would have been really interesting, so I'd better work really hard to be up to the task. Even because I know that the conference normally has quite a high bar...

It is always difficult to pick one of the talks that are held at the same time, and this year I will lose one more than I did in the previous years. I hope all sessions will be recorded, as it seems, so I'll be able to see them later.

Meet you there... And don't forget to register and donate :-)

Monday, October 10, 2011

Agile Day: independent, thanks to donations

The Agile Day is an event organized by members of the Italian agile community.

To mantain its independence, and at the same time guarantee both a quality programme and free access to registered attendants, in the last years the Agile Day has chosen a brave strategy: sustain itself with self-financing.

This choice has proven itself effective, and the Agile Day has reached its eighth edition and more than six hundred attendants in 2010.

The donations obtained from participants, enthusiasts and professionals that daily work with agile methods represent the esteem and the affection that the Agile Day has been able to conquer year after year.

All the raised money will allow the organization to reach the organizational targets that will make a great Agile Day.

That's why everyone committment becomes essential, every single donation is a step towards the success of the Agile Day.

The Agile Day will be held in Rome on November 19, 2011.
The access will be, as always, free.
All details can be found on the official site.

Sunday, October 2, 2011

PMBA & The Frankenstein Garage experience

Who we are

We are a small team of IT experts, and we have been working for a while trying to create something of our own, in addition to our daily jobs. We definitively are bootstrappers, because we don’t have so many bucks in our pockets (and even if we had, we’d want to use each penny wisely).

How it started

We knew pretty well that being an expert on a given technical subject is not enough to help you start a business. None of us has an MBA, but we wouldn’t let that hinder us, so we have started reading a lot of business related books - actually devouring them: finance, marketing, business, innovation. We wanted to reach a level of understanding similar to that of an "institutional" and much more expensive MBA. Being technicians, we're really pragmatic and believe in practical and operational knowledge, so we’ve rolled up our sleeves and delved into the groove.

Frankenstein Garage

The project we’re working on is called Frankenstein Garage, and it’s going to be the first FabLab in Milan. FabLab stands for Fabrication Laboratory (but also for Faboulous Laboratory), and it is a place where people can make (almost) anything. The first FabLab was born at the MIT in Boston to support a course held by Neil Gershenfeld. The laboratory, beyond the usual tools you can find in any lab, will have tools for digital fabrication, like 3D printers or CNC machines: this means that the machines will sort of “automagically” build things out of CAD drawings.

We employ waste materials (electronic, electric and mechanical) to develop low cost prototypes and to be green. Our experience in the IT world has taught us that being agile is the right choice almost in everything: that’s why the early stage of our prototypes heavily involves the use of LEGO bricks.

To sustain our activities we have developed our MEVO: the ABNormal, a little micro-controller board, which we’ll be ready to sell in a matter of days.

How PMBA helped us

A few months ago we have found on Google a link to Josh Kaufman's wonderful list of books, to find that we had already read many of them. Obviously we've bought PMBA as soon as it became available, read and re-read it and, most of all, started to use it, putting into good use all the knowledge distilled into it. We consult it almost daily and follow the advices contained in it each and every day: Kaufman's work has proven really useful for very busy startuppers like us.

As PMBA helps us a lot as a quick reference, we have also created some mind-maps from the book, to achieve faster results: seeing all the concepts in a single glance is really effective and a great time saver, as we can now check multiple aspects in just one shot. This has helped us to develop clear concepts and refine our proposals in an acceptable Business Plan (by the way, Business Model Generation has helped us a lot to prepare for the BP, when shall we see it in the list?).

Following the advices found in the book(s) we also won two awards just a few weeks after starting this project: "Dall'Idea all’Impresa" e "Diamo casa a 10 idee creative", which more or less sound like "From idea to business" and "Let’s host 10 creative ideas". That won us, among other services, a free office for year in Milan, and that is really helping us as it means a great saving, leaving our (small) resources for other uses.

Interested? check out the official Frankenstein Garage page!

Friday, September 23, 2011

Angry Birds slung from WhyMCA to Vimeo

The video of our talk on Angry Birds is finally online!



All details can be found on the official site. Thanks again to Paolo for putting up with me and to the organizers of the event. Looking forward to WhyMCA 2012 :-)

Tuesday, September 20, 2011

Hard times for reading stats

This year I have no time for reading. I really try, but I can't manage to save myself some time. Up to now I have only read 29 books in 2011, and the last one I finished is a book I started to read in January. What a shame.

On the other hand, I've got my hands dirty in a lot of things, and this partially justifies the stats. I don't see a lot of free time in my immediate future, but I hope this will change. I still have more than 150 books to read, not to mentions the ones that I have not yet registered in anobii.

Nevertheless, I am looking forward to the 8th of October, not only because it is the anniversary of my friends Katia and Nea, but also because "The Lean Startup", an absolute must have, will arrive on the shelf of my favourite bookstore.

That said... I'll delve into one of the nine books I'm reading. At the moment, the target for 2011 is a modest 36 (exactly the half of last year), we shall see whether I'll reach it or not.

Thursday, August 25, 2011

Page Hyerarchies in WordPress

While implementing the information architecture of a website based on WordPress, I kept trying to create a hyerarchy between the pages, failing over and over because the "parent" select was nowhere to be seen, even if the label was plainly there, happily mocking me. I googled for what seemes forever without coming out with anything good.

What a fool. The answer was there, all the time.


Yet, it just required the smallest amount of brain one can think of. It was Alessandro that pointed me to the simplest solution of them all: you have to publish your pages BEFORE you can use them in a hyerarchy. That's all :-)

Tuesday, August 16, 2011

NetBeans IDE 7 Cookbok: a review

After three intense weeks, the last one of which spent tiling floors (I definitely need to improve my speed as a tiler), I've finally been able to complete the review of the "NetBeans IDE 7 Cookbook" by Rhawi Dantas published by Packt.

The book is a collection of recipes (quoting from the text)

...for everyone that wants to try NetBeans or is beginning with a new technology and would like an uncomplicated way to setup and start coding.

Each recipe consists of four different sections:
  1. Getting ready: it tells you what you will need to follow the recipe (a sort of ingredients list)
  2. How to do it: the recipe itself
  3. How it works: an explanation of what is going on behind the curtains (or should I say in the larder?)
  4. There's more: slight variations or new insights (try adding more red hot chili pepper)
Before delving into the actual review, a disclaimer is due. I am a NetBeans Certified Specialist, and I have used it since it was not NetBeans yet, so I'm not exactly the intended target for the book and I might get extra critic (did I say "might"? I surely will). That said... let's tuck in (we're talking about recipes, so the bad pun is intended).

As I said, the book uses a very clear font and has very good and detailed pictures that help you follow the recipes. Sometimes they are a little different from the actual ones, but that is probably due to the fast pacing changes of the software, and this is never a real problem.

All explanations are clear and easy to follow, even if some are too simplistic, of the kind that makes you say "so what?". The most annoying thing are the uncountable typos, which are in no way accountable to the author, whose main job is to focus on the content.

I didn't like the recipes structure for different reasons. One of them is that sometimes one or more sections are useless: I really don't expect to find sentences like "...if NetBeans is not currently installed...", what's more I don't expect to see them more than once. Another one is that this structure gives way to a lot of repetitions, which as a (good lazy) developer I try to avoid whenever I can. This is particularly obvious in recipes strictly based on the previous ones. A simple organization in linear chapters would have been much better.

Another thing I didn't like is the organization of chapters: why wait until chapter 9 for refactoring and until chapter 11 to write about tests, moreover mixed with profiling? In chapter 9 it is said "..refactoring could break code...", and where can you find a better place to introduce tests? (this is a rhetoric question, so if you're answering "chapter 11" either you're wrong or I badly am).

The old but still good NetBeans IDE Field Guide had a very different first chapter, which I really appreciated: this is where you get NetBeans, this is how you install it, this is how you create a project, this is how you run it. New class, new method, new test class, debugging. A few pages and you've covered most of what you'll ever need. And you never have to get back on it.

On the other hand, here I have to wait 200 pages to find that CTRL+R renames almost everything, and a lot of refactoring are forgotten. And the preview option is discussed only ahead in the chapter instead of with the first refactoring.

Another thing I didn't like is a chapter that requires version 6.9: if this is a cookbook based on version 7 you should stick with it, at the most mentioning the fact that the previous version also supported JavaFX. There are so many things that are not supported anymore that could fill another book. By the way, when will we have Struts2 natively integrated instead of Struts1?

Leaving aside the fact that the chapter on version control does not deal with cvs (ops... did I write it aloud?) I was a little disappointed by the fact that most of the interesting things about the IDE are never mentioned: how do I start it with a different JVM? how can I configure projects for each developer's unique environment? (I know it is an antipattern, but it happens even in the best families). What are libraries in the NetBeans vocabulary (a hint: they are not jars) and how do you manually edit them? Shall we talk about the very powerful editor? where are code templates, except for the python example in chapter 10 in which is never said how to distribute your plugin or what the NetBeans Platform is? Can I only generate a web service from an EJB? (another rhetoric question). And many, many more.

All in all, the book is not that bad, but in my grumpy-old-man biased opinion it does not get past a 3 out of 5. Obviously you don't have to entirely rely on my words, as you can download the free chapter on EJB which you can use as a means to get a general impression.

Thursday, July 28, 2011

Coming soon: a review on NetBeans IDE 7 Cookbook

NetBeans users (and curious) stay tuned, I'll be soon reviewing the "NetBeans IDE 7 Cookbook" by Rhawi Dantas published by Packt.

I received it yesterday and the first impression is good, there are many clear images and it seems very easily readable, with nice and untiring fonts - as you can easily verify taking a peek at the free chapter on EJB (which only has the little annoyance of being distributed in black and white while my e-book comes in full color). Yet, it's a little bit too early to say something about the content :-)

This is the first book on the subject I read since NetBeans IDE Field Guide was published in far 2006, so a comparison seems due. You may freely skip the rest of my rants and check for updates in about three weeks.

Wednesday, July 27, 2011

Our submissions for Italian Agile Day 2011

After breaking the ice at WhyMCA Paolo and I decided to submit a talk for the 8th Italian Agile Day which will be held in Rome on november 19, 2011. Then we lost a bit of control of the situation and submitted three :-)

Unlike most of the presentations we have seen delivered in the previous editions, mainly about technology and methods, which are the expected core subjects of the conference, we have submitted a proposal for a talk about business aspects.

We still don't know whether one or more of our presentations will be accepted; at the moment they're in for the perfection game, in which other submitters and the organizers can give their feedback on the title and the abstract of our talk to help us improve them (or to rule us out).

The abstract so far:

Startup without falldown: strategic planning beyond wishful thinking

Creating an app, even if successful, does not mean creating a startup. A startup serves the purpose of discovering and validating a sustainable business model, so the first thing your financial backers ask you is a business plan.

The best way to create one is to dice a little (the best dice are the multi-sided ones used in D&D as they add a nice variance to the results) and put the outcomes on an Excel file, possibly coupled with a presentation filled with bullet points, incomprehensible charts and never ending description blended with bad quality images.

And then? then you clash with the market.

Luckily there are alternative tools: together we'll see how to combine customer development and the business model canvas to analyze the business and to validate the chosen model.

Read all about our other proposals on Paolo's blog.

Wednesday, July 20, 2011

A little bit of customer development

After having a great fun at WhyMCA, Paolo and I are thinking of submitting a proposal for a speech for the 8th Italian Agile Day. Up to now we have two or three ideas, but, eating our own food, we should "get out of the building" and test the market to verify our hypotheses.

Up to now, we're interested in a business oriented talk and in prototyping. Maybe Alessandro will join us as well on the latter.

More on this will follow, but if there are any subjects you'd like us to speak about please let us know. If once was enough, or even too much, please let us know as well :-)

Tuesday, July 19, 2011

Italian Agile Day 2011!

Even an earlier bird than I was last year, I'm happy to announce that the 8th Italian Agile Day will be held in Rome on November 19, 2011.


It is a one day free conference on Lean Development and Agile methods for developing and managing software project aimed at developers, project leaders, IT managers, testers, architects and coaches with experiences to share or that are just beginning to dip into these themes.

Its declared aim is to share practical knowledge, experiences on the field and achieve an active involvement by all the participants.

Free access upon registration, limited seats. For the fifth time running, the event will be self-financed.

Monday, July 11, 2011

Fat

And the whole world knows I'm fat and I'm proud
Just tell me once again who's fat

There are only two kinds of people

Those who can extrapolate from incomplete data

Wednesday, June 22, 2011

Baboons bash the Welsh

As unbelievable as it might seem, for the seventh year in a row (which means since the trophy was born) the Ingolstadt Baboons won the most important trophy of the Milano Rugby Festival 2011(you got it, we're talking about the Cassie Pienaar trophy, awarded to the team that drinks more beer). The stats report the astoundish number of 350 beers in three days, which was barely enough to beat the Gwent Police team from Wales. And there were only eight Baboons! (no, we didn't count Mr. Zulu)

I'm told there have also been some rugby matches (actually about 150), at the end of which the Cup went to the Clandestinos, who came all the way from Argentina. The Vets cup was awarded, for a change, to the Alcolizzati, that also featured the best player in the category (way to go Luca!).

I hope next year I'll be part of the game: we are already thinking of restoring our old sevens team, the Isotopes (I was 232Th). Of course time passes for everyone, so we'll feature the Decayed Isotopes. Maybe our old grey shirts will be replaced with yellowish or greenish ones. Or maybe not... after all, thorium decays in about 14 million years...

Wednesday, June 8, 2011

Milano Rugby Festival 2011

Though I have been very busy, I cannot help reminding everyone of the 2011 edition of the Milano Rugby Festival, which will be held in Cernusco this weekend. All the details can be found on the official page of the tournament. See you there, and remember: left hand drinking only :-)

Friday, May 20, 2011

Angry Birds at WhyMCA

Today Paolo and I have held our speech on the reasons beyond the huge success of Angry Birds.

First of all we would like to thank all our attendees, that decided to spend an hour of their time with us. Too often we only think of what we will say or do in a presentation, and we can easily forget that a lot of people would waste their time if we don't take this responsibility very seriously. We hope all the time we have spent preparing the speech has translated in even the smallest improvement for people who choose to listen to us. The hall was crowded, but then again maybe the other ones were too full and people were looking for a place where they could find a seat and sleep for a while after dinner :-)

The other thanks are for the organizers of the conference, whithout whom all this would not have been possible. They were even so nice as to give us a beautiful t-shirt for free... and I even won a mug :-)

Here are the slides of our speech:

I suppose they are not very easily comprehensible without the speakers, but at least I am told the pictures are nice :-)

All constructive comments, positive or negative as they might be, are highly welcome: help us to improve!

Thursday, May 12, 2011

Why WhyMCA

The countdown says 5 days until the revolution, meaning that we only have a few days to finish (and rehearse) our presentation. I am having a lot of fun preparing for the event, and I am learning a lot too, but it is no bed of roses: in the end we have chosen a little less than a hundred images, some of which were manipulated and some others entirely created by us, not to mention all the mind maps made in preparation. Should we give them as handouts at the end of our speech? Slides would not be very useful without us... we tried to avoid the "death by power point" syndrome, but only the audience will tell whether we succeeded or not.

But why did we decide to get in there in the first place? after all I do not develop games, nor am a mobile expert, yet here I am, talking about the cognitive process at a conference for mobile activists. Simply put, Paolo asked me :-) but that would be too simplistic a statement. It's been a while since I first felt that maybe after getting so much from so many engaging speakers the time had come for me to give back a little something as well, but I was looking for something interesting to say. It looks like I found something that interests me, both because it is out of my comfort zone and because it is about games, that used to take so much of my time (well that was before my wife framed me with house maintenance). Maybe it could be of interest to someone else as well.

So, why is Angry Birds such an enormous planetary phenomenon? Come find it out at WhyMCA :-)

Thursday, April 21, 2011

Angry Birds invade WhyMCA

On May 20 I'll be presenting with Paolo at WhyMCA Mobile Developer Conference in Milano. Our presentation will start from Angry Birds, the all famous blockbuster mobile game, to introduce the concept of patterns in games, loosely following the ideas presented by Raph Koster in A theory of Fun for Game Design.


The abstract: 12 million paid downloads, 100 million downloads, 50 million Euros under the belly. Why has everyone with a smartphone played Angry Birds? Why is it so addictive? How is it different from games not designed for mobiles, and how is it equal to them? What are the patterns beyond a successful game? Do they hold only for mobile? Is finding them an art, or are they reproducible? Let's find out why the answers are hard wired in our brains.

Read all about it here.

Wednesday, March 30, 2011

Duplication is evil, double duplication is worse

Think of an application with a domain model in which a person can have several emails, each of which has a different role (e.g. private, office, preferred, and so on). Persons can choose their preferred email for normal communications, but there are other communications that are normally sent to the email with a given role (e.g. communications about personal health will not be sent to an email which is also read by secretaries); only when an email with this role is missing the system reverts to a default email, which is chosen between the existing ones applying a chain of rules.

In an application like this you could (hypotetically speaking, of course) find a snippet of code that returns the email corresponding to a given role:
public String getEmailForRole(Role role) {
String email = emails.get(role);
return email != null && isValidEmail(email)
? email
: getDefaultEmail();
}

public boolean isValidEmail(String pattern) {
return (...stuff...);
}
The isValidEmail method checks the email against a simple regular expression. This snippet springs at least two different considerations.

Check for correctness

One might think that the check for validity is unnecessary, after all checks are done while inserting and updating, right? Partially. Let's just say all checks should be done there, and let's not forget that data greatly outlive applications, so you could easily have strings with completely different meaning stored where only emails should be. Sounds ugly? Welcome to reality. Sure, you could quite easily find all instances of strings that are not emails, but when the customers asks you to leave stuff as it is you have very little power. Other things I've seen include courses descriptions instead of teachers and documents instead of relatives. To cut a long story short, better safe than sorry.

Be clear on intents

Stick with them and hide mechanics. In particular, here we have a duplicated duplication (pun intended):

  • the check for null values must be duplicated in every snippet that contains emails.get(role)
  • the check duplicates the intent of the isValidEmail method. I think this duplication is worse than the previous one, first of all because the redundancy blatantly hits the eye, but most of all because there is a conceptual duplication: the responsibility for the check should lie in the idValidEmail method itself.

If there's an isValidEmail(String pattern) method I expect it to check for null values without having to bother myself:
public String getEmailForRole(Role role) {
String email = emails.get(role);
return isValidEmail(email)
? email
: getDefaultEmail();
}

public boolean isValidEmail(String pattern) {
return pattern != null && (...stuff...);
}
A more elegant solution could be the creation of an immutable Email value object and the use of the NullObject pattern, a special case of the more general Special Case pattern (another pun intended); in this case the emails object would return a NullEmail object that implements the same interface of the Email class:
public Email getEmailForRole(Role role) {
Email email = emails.get(role);
return email.isValid
? email
: getDefaultEmail();
}
A simplistic implementation of the NullEmail object could be
class NullEmail {

private Role role;

public NullEmail(Role role) {this.role = role;}

public String getValue() {return "";}

public Role getRole() {return role;}

public boolean isValid() {return false;}
}
If we wanted to explicitly return a String instead of an Email object we could slightly modify the getEmailForRole method:
public String getEmailForRole(Role role) {
Email email = emails.get(role);
return email.isValid
? email.getValue()
: getDefaultEmail();
}
As you might have noticed, nothing changed in our NullEmail class - nor in the Email class, which is not shown here.

Of course in this particular case we still have to check for the validity of the email, but in many other places (e.g. print emails of a person for every possilbe role) we can safely operate on our NullObject just as we would on a valid one.

It could be overkill, but it surely gets rid of one of the worst plagues in software: duplication. But that's the subject for another post :-)

Saturday, March 26, 2011

On "Working Effectively with Legacy Code"

In the last few weeks I have spent most of my time working on a legacy system which is going to be partly replaced by a new one which greatly broadens its scope. But what exactly is legacy code? Michael Feathers says that
To me, legacy code is simply code without tests.

It is as simple as that:
Code without tests is bad code. (...) With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse.

Alas, too often the answer is not the one we'd like to hear.

We started out so well

Almost every system, if you have at least decent programmers working on it, starts out as a wonderful green field: defined architecture, code conventions, solid principles, patterns and practices.

After a while the gardeners get busy with other gardens, and a couple of weeds start to poke out. Then some more, then more. And more. Meanwhile seasons pass and rain falls, so our green field gets muddier and muddier. Actually it looks more like it has rained cats and dogs, day after day after day. Mud becomes quicksand, and nobody dares to even get close to it.

The (in)famous spaghetti incident

Too soon the project reaches the point in which whenever you pull a string you have an undesired and often undetected change in a completely different part of the system. When I want to sound important I refer to this as the butterfly effect, a metaphore used in chaos theory. Yes, I know that your projects are different and you have never seen it happen, so try to use your imagination and stay with me a little more, will you?

That was exactly where I was, all tangled up in obscure dependencies: the perfect spaghetti code.


As I tweeted, I love spaghetti when they are in my dish, not in my code, so I had to do something (even because deadlines are always waiting in ambush). To sharpen my tools I retrieved my copy of "Working Effectively with Legacy Code". The book covers many aspects of what we developers have to face daily: instead of the "write once, run anywhere" mantra, we have to deal with "write once, read it at least ten times", but too often our code is obscure. Yes, our code. And we don't have tests, or at least we don't have enough. Do you have a complete coverage? If you do, you have all my respect, otherwise welcome in the family.

How do we get out of this?

First of all, we have to get our code into a test harness, but it is not as easy as it sounds. The book contains a series of 24 different dependency breaking techniques, each of which presented in several almost-real situations, to minimize the impacts of changes and ensure that we are not breaking anything. It sounds like the classic catch-22 thing:

When we change code, we should have tests in place. To put tests in place, we often have to change code.


This is where the techniques come in handy. I was pleasantly surprised when I discovered that, after some years of TDD, almost every problem and solution described in the book sounded familiar, so I skimmed it more than actually reading it. I still remember when I first read it: man it was hard, not the writer's fault, but because of the reader.
One of the most important things is that you have to preserve the behavior of your system when you refactor it (and preserve the rest of the system when you introduce new features or change existing ones), so you should at least know what it does. What is better than some characterisation tests?

Cleaning it up

I love NetBeans. I always have, since it was Forte4Java. Now I love it even more because it has a heap of automated refactorings that make "Refactoring" needless (ehm... that's not true, NetBeans deals with the mechanics, but you should know what you're doing, so stop reading and go buy your copy if you still don't have it. Done? OK, let's get on).

Do you need to create a new test class? nothing simpler, just a simple SHIFT + CTRL + U and a template with all the skeleton methods is ready for you. Just punch in the starting conditions and the expected results and you're done. Feathers describes all refactorings steps by steps, but a few keystrokes are all NetBeans needs to extract superclasses, methods, interfaces, pull up or push down members and methods, delegate, and so on and so forth. Nevertheless, you should know what you're doing.

While working your code could get uglier in some places. It could be temporary, or temporary in the Italian way (which means definitive). Even in the latter case, at least you would have tests in place so that you know you're not breaking anything.

In several places Feathers suggests to reduce incapsulation to put code into a test harness. Somebody might find it strange, extremists might find it insane. Yet...

Encapsulation isn't an end in itself: it is a tool for understanding.


Remember when I wrote that you write code once and read the very same code over and over? What 's the point of an encapsulated design if I spend hours for the most trivial task? Mnd you, I'm not suggesting every field must be public and collections should be directly exposed, but nobody is going die if a private method becomes protected for the sake of testing.

Where have my spaghetti gone?

After a while, one after the other, your pull spaghetti out of your dish, slowly replacing them with neat and tidy sushi.

Before you realize it, you will look at your codebase with different eyes, and chances are that you will enjoy dealing with legacy code. Don't enjoy too much though, even if you have a lot of technical debt to pay: you don't have to pay it for the sake of doing it, but because it allows you to move faster when you need it (and you know you will need it).

Let me stress this again: if I didn't have some hundreds of tests already in place, these weeks would have been months. Baby steps, nip and tuck, red and green bar. But I only introduced tests and refactored legacy code when I needed it, otherwise I would spend too much time on activities that were not a priority. See something rotten? pen it down, fix what you're doing and if you still have time you can deal with it. Look for decisions that could change, but change your code just in time (the YAGNI rule rules).

Tuesday, March 8, 2011

How to use Java to call an IBM i program

This post is a late update to a post I wrote a couple of years ago about exposing RPGLE programs so that we could call them from our webapps. That worked fine, but I didn't particularly like the workflow we used to produce the wrapper, so I tried to get rid of some muda.
The worst one was, in my opinion, the need to use two different IDEs, thus necessarily involving the collaboration of two persons (not every developer has IBM tools) that creates a bottleneck.
After some researches I found some official documentation (the problem with IBM is not scarcity but abundance), dug for our jt400.jar and started to experiment a little.

A small word of caution: the article is written in an introductory style, showing the TDD process that lead to the implementation of the functionality I needed. If you're only interested in the results you can easily skip to the end of the article (I will not know it, so I won't get offended).

The guinea pig for my experiment is a simple program that given a table name returns a serial number which is unique for that table. As I had have to use this program in an application that already uses a serial number generator, first I need an interface, so I use the NetBeans Extract Interface refactoring on my existing service:
public interface SerialsService {
long getSerialNumber(String tableName);
}
That done I create an implementing class that gets the serial from the iSeries:
public class MyIseriesSerialsService implements SerialsService {
public long getSerialNumber(String tableName){
throw new UnsupportedOperationException();
}
}
OK now we can start the real stuff. First thing first, we write a couple of simple tests in a new test class:
@Test(expected = "IllegalArgumentException.class"
public void testWithWrongTableNameShouldThrowException() {
MyIseriesSerialsService instance = new MyIseriesSerialsService();
instance.getSerialNumber("WrongName");
}
CTRL + F6 to start the test and NetBeans gives me a red bar. I change the type of exception thrown, CTRL + F6 again and here's a nice green bar. That was easy, wasn't it? now we have a service that behaves correctly when you don't invoke it correctly. This is good, but if your application is like mine I suppose you expect your service to behave correctly even when it is correctly invoked (yes, sometimes it happens).

To call an IBM i program you first have to connect to an iSeries, and for this you use the AS400 class, which IBM documentation actually calls AS400 IBM® Toolbox per Java™: I'll stick to that, so that is what I mean when I simply write AS400 - the same holds true for all other registered trademarks. If this is enough to keep lawyers at bay, as I hope, this ends the disclaimer.

The AS400 class, amongst other things, manages socket connections on behalf of a user, so at least we have to tell our service what is the iSeries we want to connect to, and which user we want to impersonate. This requires to change the constructor of the service (obviously it is not the only way, but I'd rather use an immutable object). We could pass in the name of the server (or the ip address if you don't want to rely on a DNS service), a username and a password, or we could create an AS400 object and pass it to the constructor of the service. This option separates responsibilities better (and can be tested more easily), so I choose it and write a simple test to check the connection to our system:
@Test
public void testConnection() throws Exception {
AS400 system = new AS400(host, username, password);
assertNotNull(system.getRelease());
System.out.println(system.getRelease());
}
I am just experimenting, so as always I defer all the exception dealings. Green bar. I can now add a field to the constructor of the service...
public class MyIseriesSerialsService implements SerialsService {

private AS400 system;

public MyIseriesSerialsService(AS400 system) {
this.system = system;
}

public long getSerialNumber(String tableName) {
throw new IllegalArgumentException();
}
}
...and modify the tests accordingly, also removing a small duplication:
@Before
public void setUp() {
instance = new MyIseriesSerialsService(createValidSystem());
}

private AS400 createValidSystem() {
return new AS400(host, username, password);
}

@Test(expected = IllegalArgumentException.class)
public void testWithWrongTableNameShouldThrowException() {
instance.getSerialNumber("WrongName");
}
Skipping (for the sake of the article) all tests on invalid systems and other exceptions we can now start writing a more interesting test:
@Test
public void testGetSerialNumberReturnsPositiveNumber() throws Exception {
long result = instance.getSerialNumber(tableName);
assertTrue(result > 0);
}
CTRL + F6, red bar (as expected). This is where the rubber hits the road.

The MYPGM program is contained in the MYLIB library in the QSYS, and it also uses the MYOTHERLIB library (by the way, watch for the maximum length of the names of the libraries, which is 10). The wrapper class for a program call (the Command pattern in action) is ProgramCall (fantasy does not abound in IBM, but that's good as I easily found what I was looking for). It needs to know the system we're operating on, the path to the program and the parameter list. We have the system, so we need the path to the program, for which we use the QSYSObjectPathName class, and the parameter list, for which we use the ProgramParameter class.

The QSYSObjectPathName constructor takes as parameters the name of the library, the name of the program and it extension. Once we have a QSYSObjectPathName object we can ask it the path to the program, which is what precisely what we need:
QSYSObjectPathName pgmName = new QSYSObjectPathName(myLib, myPgm, pgmExtension);
The parameter list is actually an array of ProgramParameter objects, which cannot be null. Each parameter wraps an array of bytes, so we have to use the proper converter; luckily there are some converters ready for us.

Our program has an input/output parameter (the name of the table) and an output parameter (the serial number for the given table), so we have the following:
ProgramParameter[] paramList = new ProgramParameter[2];
The first parameter is the name of the table, which is a String. To deal with it we can use the AS400Text converter:
AS400Text textConverter = new AS400Text(10, system);
byte[] key = textConverter.toBytes(tableName);
paramList[0] = new ProgramParameter(key);
The first parameter for the constructor is the length of the IBM i text, the second one is the system we're operating on.

The output parameter is a long, so we'll have to use a different converter. Up to now let's just initialize it:
paramList[1] = new ProgramParameter(32);
Our command is now ready to be born:
ProgramCall pgm = new ProgramCall(system, pgmName.getPath(), paramList);
To execute it we simply call the run method, which returns a boolean. If the result is true we can extract data from the output parameter and convert it:
byte[] data = paramList[1].getOutputData();
AS400PackedDecimal pdconverter = new AS400PackedDecimal(12, 0);
long result = ((BigDecimal) pdconverter.toObject(data)).longValue();
And this is it. Let's see:
Testcase: testGetSerialNumberReturnsPositiveNumber(testserialias.MyIseriesSerialsServiceTest):
Caused an ERROR
6
Wow that's illuminating... Luckily we aldready know what's going on: if you check above you'll notice I wrote that the program needs another library, which is not loaded when we first connect to the system. To add the library we need to issue a command, thus we use the CommandCall class:
CommandCall cc = new CommandCall(system);
cc.setCommand("ADDLIBLE " + myotherLib);
cc.run();
Now we're going somewhere... As we trust but also want to control we add another simple test to check that the service returns bigger numbers on consecutive calls:
@Test
public void testGetSerialNumberReturnsBiggerNumbersOnFurtherCalls() {
firstResult = instance.getSerialNumber(tableName);
long secondResult = instance.getSerialNumber(tableName);
assertTrue(firstResult < secondResult);
}
If we want to have more informations we can ask the program wrapper for an array of AS400Message objects:
private String buildMessage(final ProgramCall pgm) {
AS400Message[] messageList = pgm.getMessageList();
String message = "";
for (int i = 0; i < messageList.length; i++) {
AS400Message aS400Message = messageList[i];
message += aS400Message.getText();
message += "\r\n";
}
return message;
}
The RPGLE program already ensures that no serial can be duplicated, but I thought that adding a little bit of safety wouldn't be too much damage, so the main call is synchronized. The final draft:
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;
import com.ibm.as400.access.AS400PackedDecimal;
import com.ibm.as400.access.AS400Text;
import com.ibm.as400.access.CommandCall;
import com.ibm.as400.access.ProgramCall;
import com.ibm.as400.access.ProgramParameter;
import com.ibm.as400.access.QSYSObjectPathName;
import java.math.BigDecimal;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyIseriesSerialsService implements SerialsService {

private final String myLib = "MYLIB";
private final String myOtherLib = "MYOTHERLIB";
private final String myPgm = "MYPGM";
private final String pgmExtension = "PGM";
private final AS400 system;
private QSYSObjectPathName pgmName;

public MyIseriesSerialsService(final AS400 system) {
this.system = system;
addLibraries();
createPathName();
}

public long getSerialNumber(final String tableName) {
synchronized (this) {
ProgramParameter[] paramList = createInputParameters(tableName);
ProgramCall pgm = createProgramCall(paramList);

try {
pgm.run();
} catch (Exception ex) {
Logger.getLogger(MyIseriesSerialsService.class.getName()).
log(Level.SEVERE, ex.getMessage(), ex);
String errorMessage = buildMessage(pgm);
throw new RuntimeException(errorMessage, ex);
}

long result = extractResult(paramList);

return result;
}
}

private void addLibraries() {
try {
CommandCall cc = new CommandCall(system);
cc.setCommand("ADDLIBLE " + myOtherLib);
cc.run();
} catch (Exception ex) {
Logger.getLogger(MyIseriesSerialsService.class.getName()).
log(Level.SEVERE, ex.getMessage, ex);
throw new RuntimeException("Unable to inizialize service", ex);
}
}

private void createPathName() {
pgmName = new QSYSObjectPathName(myLib, myPgm, pgmExtension);
}

private ProgramParameter[] createInputParameters(final String tableName) {
ProgramParameter[] paramList = new ProgramParameter[2];
paramList[0] = createInputParameter(tableName);
paramList[1] = new ProgramParameter(32);
return paramList;
}

private ProgramParameter createInputParameter(final String tableName) {
AS400Text textConverter = new AS400Text(10, system);
byte[] key = textConverter.toBytes(tableName);
return new ProgramParameter(key);
}

private ProgramCall createProgramCall(final ProgramParameter[] paramList) {
return new ProgramCall(system, pgmName.getPath(), paramList);
}

private long extractResult(final ProgramParameter[] paramList) {
byte[] data = paramList[1].getOutputData();
AS400PackedDecimal pdconverter = new AS400PackedDecimal(12, 0);
return ((BigDecimal) pdconverter.toObject(data)).longValue();
}

private String buildMessage(final ProgramCall pgm) {
AS400Message[] messageList = pgm.getMessageList();
String message = "";
for (int i = 0; i < messageList.length; i++) {
AS400Message aS400Message = messageList[i];
message += aS400Message.getText();
message += "\r\n";
}
return message;
}
}
And the test class which assisted me in all the small refactorings:
import com.ibm.as400.access.AS400;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class MyIseriesSerialsServiceTest {

private final String host = "myVeryExpensiveHost";
private final String username = "myUsername";
private final String password = "myPassword";
private final String tableName = "myTable";
//
private MyIseriesSerialsService instance;

@Before
public void setUp() {
instance = new MyIseriesSerialsService(createValidSystem());
}
private AS400 createValidSystem() {
return new AS400(host, username, password);
}

@Test
public void testConnection() throws Exception {
AS400 system = new AS400(host, username, password);
assertNotNull(system.getRelease());
}

@Test(expected = IllegalArgumentException.class)
public void testWithWrongTableNameShouldThrowException() {
instance.getSerialNumber("WrongName");
}

@Test
public void testGetSerialNumberReturnsPositiveNumber() throws Exception {
long result = instance.getSerialNumber(tableName);
assertTrue(result > 0);
}

@Test
public void testGetSerialNumberReturnsBiggerNumbersOnFurtherCalls() {
long firstResult = instance.getSerialNumber(tableName);
long secondResult = instance.getSerialNumber(tableName);
assertTrue(firstResult < secondResult);
}
}
As I said, this is but a draft, and could be improved in many ways, e.g. the tests are quite coarse and don't consider all the small things that could go wrong, some of which I discovered with a quick debugging while I was setting up the tests. Calling a system.disconnectAllServices() when you finish would not be bad either. Yet, it is easily readable and hopefully understandable, so I hope this will help everyone to get rid of the extra stack required by the application server when it is not needed (does that ring a bell?).

Thursday, March 3, 2011

About planning and emergency

The title was inspired by Davide Bianchi, that posted out of his office a sign that reads "Pianificazione schifosa dalla tua parte non รจ emergenza dalla mia parte", which more or less means "if you don't know what planning is about, don't come here complaining, because I have my own priorities". Or, to quote something a little farther on the timeline, "frankly, my dear, I don't give a damn".


It is true that no plan survives the contact with the enemy, but planning is essential. It is one of the core practices of risk management, which, as Tom DeMarco and Timothy Lister write in Waltzing with Bears, is "Project Management for Adults". What are the risks? You have to look ahead, and decide how you want to deal with them. Of course hoping for luck is an option... but how good is it? Sometimes you can count on it, maybe because even if your luck abandons you it'll affect but a small portion of the whole project. But, honestly, do you really think that none of those twenty or thirty bad events is actually going to happen? Do you know what the odds are for a chance like this? I was pretty good at statistics, and as far as I can remember the answer is "very, very, very low".

And this is when emergency comes into play. And, obviously, as there were no risk mitigation plans, there are no contingency plans, and your luck is having a holiday, there is a problem. As strange as it may seem, this comes as a complete surprise to many.

When planning fails (if ever there was any) the hunting season for scapegoats open. Little matters the fact that the scapegoats themselves have spent a good part of the previous months asking for a plan, or at least for directions, and trying to raise alarms of all kinds. Don't think scapegoating is something you can ad-lib, it is an art: there is also an article about the art of scapegoating in IT projects. Wikipedia reports that "Scapegoating is a known practice in management where a lower staff employee is blamed for the mistakes of senior executives. This is often due to lack of accountability in upper management."

Unlike as in Davide's office, in my experience bad planning by someone else does transform into an emergency happily hopping and bouncing on your desk. At this point, at least in the eyes of the stakeholder, quality becomes absolutely tradable, because the deadline has stopped soaring and is swooping down on them. Too bad, as what seems a saving today will cost blood and sweat tomorrow (not in a month, but within a week). Ok, maybe not blood. But I can guarantee for sweat - and money. Moreover

poor Martin Fowler
will feel so sad for all that
which is way too bad

featuring both a haiku and a link to an interesting article at the same time.

Saturday, February 5, 2011

About the (health) insurance model

This week we started a new project which purpose is to provide with a brand new system a company that deals with group health insurance. The new software will be a powerful management tool that will help our customers to boost their operational efficiency, which is already improving thanks to some non-software interventions.

While trawling for requirements during the first interview I realized that the business model on which insurance companies are based is just the opposite of the so called freemium model, in which a few paying customers (tipically about 10% of the whole population of users) subsidize many non-paying users. Paying customers are not just giving their money away though (if anybody is seriously interested in that, they can immediatly contact me and I'll be glad to help them right away), as in return for their money they get premium features not available to normal users.

Insurance is just the opposite: many customers (actually every customer) regularly pay premiums that subsidize a small fraction of users. The premium feature in this case is the (possibly partial) payment of potentially very expensive health-related bills that maybe would not be affordable by a single person: when someone claims for damages which are included in their coverage policy, the company pays.

Health insurance is then a form of risk reduction for policy holders, even if unluckily it does not reduce the risk of getting ill; on the other hand, it is a sort of a gamble for insurance companies, that bet they will collect more money than they will have to pay. Naturally it is just like gambling in every casino: it is virtually impossible to break the bank, as the premiums are based on all the odds that we could possibly think of and even more. Plus a considerable profit margin, of course :-)

Friday, January 21, 2011

FTP in Java to an IFS folder

A couple of years ago I wrote about uploading files via FTP to a remote server, ending the post reminding about the Commons Net library. Well, the time has come for me to use it, having to upload a file to an IFS folder.

The naive approach didn't work:
@Test
public void basicTest() throws Exception {
URL url = new URL("ftp://user:pass@remoteserver/path/to/remote/folder/" + "outputFile.txt");
URLConnection urlc = url.openConnection();
OutputStream outputStream = urlc.getOutputStream();

String text = "oooooo sooooleee miiiiiiiooooooo.....";
InputStreamReader reader = new InputStreamReader(IOUtils.toInputStream(text));

int mychar = reader.read();
while (mychar != -1) {
outputStream.write(mychar);
mychar = reader.read();
}
reader.close();
outputStream.close();
}
as it returned the "550-Specified library does not exist or cannot be accessed." error. Too bad. After some investigations we found that before we could access the folder we were interested in we had to issue the "cd /" command. All right, I went for the commons:
@Test
public void commonsTest() throws Exception {

FTPClient ftp = new FTPClient();
ftp.connect("remoteserver");
ftp.login("user", "pass");

ftp.changeWorkingDirectory("/");
ftp.changeWorkingDirectory("path/to/remote/folder");

OutputStream outputStream = ftp.storeFileStream("outputFile.txt");

String text = "oooooo sooooleee miiiiiiiooooooo.....";
InputStreamReader reader = new InputStreamReader(IOUtils.toInputStream(text));

int mychar = reader.read();
while (mychar != -1) {
outputStream.write(mychar);
mychar = reader.read();
}

reader.close();
outputStream.close();

ftp.logout();
ftp.disconnect();
}
Obviously this code is simplistic and pretends that errors cannot happen, but it's just to grab the sense of it. We create an instance of the FTPClient class and connect to our remote server (after all we are dealing with sockets... does that ring a bell?), then we use the normal FTP commands to reach the folder we need. After getting an OutputStream, obtained with the storeFileStream(String filename) method, we do everything like in the previous example, then log out and disconnect from the server.

Saturday, January 8, 2011

What should we write about next?

While following a tweet I found an interesting article with links to some post-mortems (the title reads 25 but there are actually 32).

After a little a small form opened up on my screen:


I must admit I wouldn't know what to answer, this being the first time I ever landed onto this site. Yet, I think it is a very good idea, as it can give the authors interesting insights beyond analytics. I mean, numbers can give you hints (you can stop blogging about foo and bar as nobody ever reads that stuff) but nothing is as worth as an advice by someone that invests her time to follow your rants AND to give you feedback.

If someone is thinking "hey that's my blog, I know what to write next" that's ok. If someone is thinking "hey that's my blog, I know what to write next, I need no hints"... well, they don't need my advice :-)

So... what should we write about next?

Friday, January 7, 2011

Toto's Africa? They need no instruments!

Listen to Perpetuum Jazzile perform Africa!

Where does good code come from?

It is a good question, and apparently several people keep asking it. I found a a visual representation of the problem:


You can find the original here, with many other interesting comics.

The interesting thing is that it seems that coding right and coding fast are like oil and water (or, to quote from the Godfather part three, like money and friendship). But is it true?

At the beginning, it surely is. But, after applying - and applying, and applying, and repeating and repeating all over again - you will actually be able to code right AND fast. That's where katas come in handy. Who knows, you might also be able to exit the "are you done yet" switch before requirements change...

Monday, January 3, 2011

The Best Way to Use the Last Five Minutes of Your Day

The title refers to this very interesting article by Peter Bregman. The core of the post is clear, and it is the importance of retrospectives, which is well known by agile pratictioners.

The sentence that struck me the most is the following one:

I was once asked: if an organization could teach only one thing to its employees, what single thing would have the most impact? My answer was immediate and clear: teach people how to learn.


It was not the first time I read something like this, yet it was more evident to me because it perfectly agrees with what the Buzans say in How to Mind Map, which I've just finished studying (I should actually say "which I've just begun studying").

This also goes hand in hand with Tom Peters, that says that each organization should work to better the condition of its employees rather than trying to gain success, which is bound to come anyway if they followed this simple rule. He also presents a certain body of evidence, so he cannot possibly have gone nuts. All the contrary.

Is your organization teaching its employees how to learn? If it is, you're a lucky guy. If it's not, you can start looking for another company, or start working on the issue yourself. Or both.

In any case, that's not an excuse: the ultimate responsible for your education is you.

The Speed Camera Lottery

This is a funny way to try to educate people to respect speed limits:



I doubt that our administrations would allow such an initiative, that would deprive their pockets; yet I wish it were feasible, as there are far too many victims on our roads.