Wednesday, December 24, 2008

Year 2008 in a nutshell

Picture courtesy of foxypar4@flickr
Christmas and New Year is coming so it's time for some summary. I've never done this before but this year was quite awesome and I have something to be proud and loud.

Let's start from January when I moved from my hometown to the glamorous French Riviera i.e Cote d'azur (yes, the sea here is pretty much azure).

I accomplished some cool stuff at work and one that I can share with you is the new generation hotel search engine - Wallaby (which is working but still in beta phase).

In 2008 I started interesting in the theory of Agile Software Development (after few years of using it) which resulted in inviting me to contributing to the AgileSoftwareDevelopment.com blog. It was a huge challenge for me as I've never been a good or even decent writer (especially in my native language - Polish) but it appeared to be kind of success. I have on my account some pretty cool posts that appeared to be big hits like these (each of the following posts was visited more than 5k times):
And the best posts were written pretty spontaneously in less than thirty minutes without any preparation. Just some kind of a thunder in my brain that triggered my grey matter to work - that was just it.

I'd like to thank Artem for inviting me to become a regular contributor - it was a good decision for me to join ASD. I hope I will keep at least the same level of inventiveness next year :)

During 2008 I've read over 18 technical books and I shortly reviewed some of them on my private blog.
More on numbers in 2008: my FeedBurner account shows quite an increase (260% from 25 to 65 - and counting) of regular readers of my private blog - that's cool. Thank you readers!

Last but not least submitting my old and fresh posts to DZone gave my private blog a lot of visibility and doing this I increased number of visits by 1000% from ~930 to over 9K in just one month (I will not be able to keep these numbers but it anyway shows me that what I write is interesting and a lot of people like it). This is also thanks to ASD blog which gave me more visibility.

And now some conclusions. As I wrote earlier I moved to southern France in January 2008 and this was caused mostly by my previous employer - Intel - who simply laid off our team at the end of 2007. My friends who I worked with at Intel opened their own company and I was supposed to be their partner but I decided to move to France with my wife. And this was one of the best decisions we made in our life.

We live in a great place, have awesome friends and every week we do some cool stuff like skiing, hiking or just visiting some beautiful places like Monaco or Eze. And this is much more important that money that I could earn staying in Poland.

I learned a lot during year 2008, the Sun hasn't burnt out my brain (yet) and consider it pretty awesome year privately as well as professionally. And I hope next year will be even better - but even if it will be a bit worse it will still be awesome :) Yes - I'm the optimist. I'm not going to reveal my professional plans for the next year but I will probably share with you the results in 365 days.

As this is my last post this year I'd like to wish all the people around the World:

Merry Christmas
and
Happy New Year 2009

Wednesday, December 17, 2008

Seven Principles of Lean Software Development - Build Quality In

Picture courtesy of WayTru@flickr
I was doing a quick research for this article using Google trying to find arguments standing for the claim that "quality is expensive". I was trying to find some resources saying that care for quality in the early stages of the software projects doesn't make sense and doesn't pay - I find it very difficult and I cannot share with you any reasonable links (maybe except for this one which refers to another post saying that "Quality Sucks").

What does it mean? It means that software people know that quality is very important. Why then quality of software products sucks in more cases than it rocks?

In many big corporations following waterfall model there is a special team named QA (Quality Assurance). This team's responsibility is (not surprisingly) to assure appropriate level of quality in the software product. This is fine, this is perfectly OK, except that QA is considered as a separate activity. This is the "Verification" or "Testing" box in the waterfall model diagram.
The biggest problem with this attitude is that QA team gets the product after it has been implemented and this is the root cause of all evil. QA is considered as something separate - we first do the product and then we care about the quality. This way of thinking is wrong. You should care about quality from the day one, before you write a single line of code.

Software teams should "build quality in" their products and QA should not be considered as a separate activity. Quality Assurance should be constant process of improving the product - QA activities and people should be involved in the development of the product during the development, not after when the developers are moved to another projects or even teams.

In this post I will try to explain "Build Quality In" principle from "Implementing Lean Software Development - from Concept to Cash" book. I will present few practices that will help your team build software with quality built in.

Synchronize
In order to achieve high quality in your software you should start worrying about it before you write single line of working code. It means that you should write test first and use all the frameworks that will facilitate your test suite (e.g. use mock objects). Track your code coverage - don't be too anal about it because 100% code coverage should not be the goal of your software but use it as an indicator to see which parts of you system should be tested more. And use all other tools that you feel are necessary to test your software thoroughly - unit testing is very often not enough.

Reduce partially done work - tasks that are 90% done usually takes another 90% of total time to finish - keep focused on one task and make it complete, then you can go to the next one. Try not putting defects on a list - stop and fix them the moment you discover them. Known bugs residing in your software will cause more defects in the future - don't allow this to happen (however issue tracking system can be sometimes useful e.g. for collecting requests from your customers).

Integrate your code as soon and as extensively as possible - commit your changes to CVS, SVN, etc. at least once a day and ensure all the tests give you green light. Don't wait with synchronization because it will hurt - you will spend more time on integration than on development. And you will get frustrated.

Automate
Even the best engineers make mistakes - you cannot avoid it - they are not robots (that may make mistakes too, btw.). Eliminate risk of mistakes by automating everything that is routine-work. Almost everything that is a repetitive work can be automated. And you should do this as soon and as early as possible - the best is to have continuous integration engine before committing a single line of code.

You should automate testing, building, installations, anything that is routine, but do it smartly, do it in a way people can improve the process and change anything they want without worrying that after the change is done the software will stop working. Automate in order to make people feel comfortable improving the software, tests, installation process, etc. by changing whatever they feel is necessary.

Refactor
Code in your software product should be as clean and as simple as possible. You can easily ensure it using static code analysers - they really work and can be a real pain in the ass for lousy developers (that's good because they will learn how to write clean code and follow the conventions).

Eliminate code duplication to ZERO - every time it shows up refactor the code, the tests, and the documentation to minimize the complexity. Using modern IDEs it's pretty simple and gives developers fun.

Build Quality In
I hope pieces of advice given above will make it easy to understand how to put "Build Quality In" principle in practice. If you need more detailed description with more examples and more sophisticated explanation you should definitely go to "Implementing Lean Software Development - from Concept to Cash" book.

PS. Four principles described earlier can be found here:
  1. Respect People

  2. Deliver Fast

  3. Optimize the Whole

  4. Defer Commitment



Originally published on AgileSoftwareDevelopment.com

Friday, December 12, 2008

Null Object - design pattern

Joshua Bloch in his excellent book Effective Java (2nd Edition) gives advice that you should never return null collection/map/array from your code i.e. instead of such code:

public List<String> returnCollection() {
//remainder omitted
if (/*some condition*/) {
return null;
} else {
// return collection
}
}
you should always use this pattern:

public List<String> returnCollection() {
//remainder omitted
if (/*some condition*/) {
return Collections.emptyList();
} else {
// return collection
}
}
This basically prevents caller of your code to get NPE while trying to do things like this:

if (obj.returnCollection().size() > 0) {
// remainder omitted

Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices gives another very similar pattern but related to ALL objects, not only to collections/maps/arrays. This design pattern is called Null Object.

Here is the example - let's assume that you have an application that check whether the user is authenticated:

public class User {
private String username;
private boolean authenticated;
// remainder omitted

public boolean isAuthenticated() {
return authenticated;
}
// remainder omitted
}
and the code that returns the reference to the User object looks like this:

public User getUser() {
if (/*some condition*/) {
return user;
} else {
return null;
}
}
This way the code that checks whether our user is authenticated should look like the following snippet:

if (obj.getUser() != null && obj.getUser().isAuthenticated() {
// allow
}
// remainder omitted
Checking whether the object is null is not only a boilerplate code but it can also give you a lot of bugs e.g. if you forget to check whether the object is null.

And here the Null Object can help you:

public class NullUser extends User {

public static final NullUser INSTANCE = new NullUser();

public static NullUser getInstance() {
return INSTANCE;
}

@Override
public boolean isAuthenticated() {
return false;
}

private NullUser() {
}
}
plus:

public User getUser() {
if (/*some condition*/) {
return user;
} else {
return NullUser.getInstance();
}
}
plus cleaner client code:

if (obj.getUser().isAuthenticated() {
// allow
}
// remainder omitted

I find this pattern very useful and really helpful. With this pattern you can really save yourself a lot of NPEs.

Still the question is whether User should be a class or an interface and then whether NullUser should extend the base class or implement the user's interface. But I will leave this decision for your consideration.

What do you think about Null Object pattern?

PS. Example I presented is not necessarily applicable in the real systems - it is here just to depict design pattern's idea. Please don't treat provided code as a solution (I can think of many improvements/changes to it depending on the context by myself) - think about it at the pattern level - not the code level.

Thursday, December 11, 2008

"I know it doesn't work but it's done" - a story about the definition of done

Picture courtesy of orinrobertjohn@flickr
Some time ago I was talking to engineers responsible for some part of the software and I was asking when they will be ready for production. In other words I asked them when their features will be ready. They told me that they are ready now. What was my surprise when I tried to test their software and discovered that about 50% of cases were not working at all. So I asked them why they told me that they are "done" when they haven't even implemented half of the planned features? They answered me: "We know it doesn't work but it's done - we implemented something so it's done. Now we have to work on quality i.e. implement rest of the features."

When I heard this I think I might have looked like the lady from the picture. I couldn't believe someone can think like this - if we implement one use case out of one hundred we can consider the project done? The rest is the "quality"? I don't think so.

In this post I'll try to explain once again what is definition of done and why it's so important to have the same definition at least among all the people involved in the development of a single project.

Let's define "Done"

I would say that there is no one, good and universal definition of done. You can find some discussions in the Internet about it but you can see that everyone has it's own variation. So do I - in my view the most important things are (I will use "user story" word meaning every variation of request, use case, user story, etc.):
  • user story has to be implemented, today (no 99.9% is accepted)

  • user story has to be tested and no known bugs should exist

  • user story is ready to go into production, today

  • user story has to be ready to be presented to customer, today

Some explanation

User story has to be implemented - means that the code has to be committed to the version control system (like CVS, SVN, etc.), documentation should be available on Wiki or in the VCS, etc. It means that the output of the work done (whatever the work to be done was) must be available for anyone in the company to be downloaded in some way and checked. There must not be "I have it on my box - will publish it soon". Work must be committed and available for others.

User story has to be tested and no known bugs should exist - means that if you know about any bugs in the user story you're going to deliver - it's not done. If it exists in some subpart of the user story and you really need to deliver the working stuff, maybe you should split this user story into two, smaller ones. You must not deliver bugs to your customer - I'm talking about bugs you're aware of.

User story is ready to go into production - it means that it is ready to be deployed at any time from the time you stop talking. The wise thing would be if the working software is already deployed and tested in the production system - if it works - it's really done.

User story has to be ready to be presented to customer - it means that within 30 minutes (max) you are able to prepare presentation of working software to your customer. Of course, it requires you to have list of acceptance test ready and you know how to demo your software. The last point of it is very very important. Remember about it when defining all your user stories - you have to know HOW TO DEMO USER STORY - it will probably help you defining acceptance tests (e.g. user adds new item to the database using HTML form, then goes to the search panel and is able to find newly created item by its name, ....).

Wrap up

As I mentioned above good and universal definition of done probably does not exist but at least many resources agree on base principles. My definition of done is simple but I consider it quite powerful.

If you are interested in diving more into the subject I would recommend those two links from ScrumAlliance:
What do you think about my definition of done? If you have your own I would gladly read about it. Please share your opinions here.

Originally published on AgileSoftwareDevelopment.com

Wednesday, December 10, 2008

Postcard from Auron

Christmas time is coming and just have to decorate my blog with some snow :)



Enjoy!

Thursday, December 04, 2008

Developers Aren't Gonna Read It

Picture courtesy of austinevan@flickr
Developers are the customers - from time to time. They are the customers for product definition/specification team that is preparing technical specification documents. It doesn't really matter whether you work in an agile or non-agile environment - I'm sure you have some technical documentation and the main goal of it is to answer developers' questions on technical issues (e.g. how to configure some components to work with others, how to map fields from GUI forms to XML message, etc.) It also helps test or QA team to prepare acceptance tests and to verify whether what developers implemented is what was specified (I know it stinks a bit the waterfall but stay tuned - I will say something about agile documentation soon).

I would suggest you reading an article on TAGRI (They Aren't Gonna Read It) by Scott W. Ambler - it's really great. And in my post I'm going to give you real-life example from what I experienced regarding documentation. I will share with you my opinions of what kind of documentation sucks and what documents are really cool and useful (btw. my dream documentation is the one with which I'm able to find accurate information of my interest quickly and be able to put this information into my head in less than 10 minutes - the picture you see is a total contradiction of my dream - it's a waterfall process).

Developers won't read it

At the beginning of the project I met with the specification creators in order to discuss what we are going to deliver. They described me the project goals, business value and the requirements, of course. They also showed me two big books (sorry, specification docs) with around 300 pages in total. And the project was quite simple - it was basic CRU (Create, Read, Update) with one type of objects to be stored and queried. Believe me - the system was simple.

I was responsible for the web UI part of this system (100 pages) but had to understand also how the backend works (200 pages). Wow! That's a lot of, for a simple system, to read - imagine how much time you need to read this. And it's nothing comparing to how much time and effort it cost to produce it - and you still have no single line of code working.

So, did I read the documentation? I didn't.

I didn't have to because I preferred direct communication with the guys who know the system throughout. I didn't have to read the documentation because the guy who specified the GUI prepared screen mockups and I knew exactly how the pages should look like. And I didn't need 100 pages of documentation for it. I just needed couple of screen mockups - it was enough for me to deliver the software.

Tests and examples are the best documentation ever

And they are not only the best documentation - they also define a design of the system to great extent. When I was integrating UI forms with the XML to the backend I was still not referring to any documentation. I just asked guys responsible for specification and preparation of tests to give me example messages (requests and responses). I got what I needed and basing on the examples I was able to integrate UI with the backend - simple. Here I will give kudos for the specification that explained how to map UI form fields into XML message (XML schema was not self-explanatory in many places e.g. I could store the phone number in different XML tags - I had to know which one I should fill). I also used a piece of documentation that explained what should be the format of input data - I had to validate user's input somehow. But that was all I needed - I used 5% (roughly) of the overall documentation stack.

KISS (Keep It Stupid Simple)

In that simple project we had three different documents and I was finding discrepancies between them almost every day - yes, some of the fields, data types, etc. were specified in all three documents (often differently). The part developed by me was quite resistant to this because I was still keeping my one source of information. If I didn't know something I just asked specification team - I wasn't looking for the answer in the documentation because it would take more time and it appeared that I was asking questions that were mostly not covered by the documentation. Again, verbal communication was the best choice for me - I was able to fix some mistakes in the documentation on the fly - because I reported every technical problem I had to those guys - they were adjusting details according to technical constraints.

To summarize this point - keep it simple. Have one source of information and you will win. I do - every time I follow this rule.

Not all documentation sucks

That's true - some level of documentation is necessary, as I showed it before. Some mappings are sometimes required, list of required fields, error codes, etc. Many of this can and should be covered by unit tests and automated GUI tests - but it's pretty hard to record GUI tests not having it. Usually in waterfall-like process documentation is considered as a good - very important good. I don't understand why? It doesn't represent any business value for the customer (except the user's guides) but a lot of people value documentation more than the working software. I think this is the reason they fail so often.

In my opinion the best documentation is the one that is very easily changeable. For example Word documents stored in Lotus Notes folders is a bad idea. Developers cannot easily change or even comment the specification/documentation - they should. I often faced the problem that I saw something really really stupid in the docs and I wanted to change it but I wasn't able. Wiki is the best option here - it's easily searchable (through many projects) and changeable. And if you want to have a Word doc - your business - just export the page to the format of your choice.

Solution

My main recommendation is to communicate verbally with people who know your product as often as you need; have one source of information - you will not be surprised by different requirements for the same thing; start with unit testing your code and keep your UI tests up to date; automate as many acceptance tests as possible - consult the results with customers (or customer proxies).

I'm not going to copy-paste the whole article but I totally support the Solution part of TAGRI article - I strongly recommend you reading it. I have nothing more to add.

What is your experience with documentation? Do you read huge stacks of papers your team lead gives you? What is the value of the documentation? Please, share your opinions here.

Originally published on AgileSoftwareDevelopment.com

Thursday, November 27, 2008

Video Tutorial on "Java Stack Traces with jps and jstack"

In one of the previous tutorials named "Java concurrency is easy: Video Tutorial on >>Detecting and debugging deadlocks<<" I made a little mistake but thanks to "Anonymous" user who commented that post I'm publishing small appendix to it. This short extension shows how to use jps and jstack tools together. Using these tools you don't have to have an access to your program's console in order to see the stack traces.

Enjoy the video!

If you want more information about jps and jstack applications refer to their home pages:

Wednesday, November 26, 2008

Customer Team Member - a way to winning together

Used by permission.
Copyright by Paweł Niewiadomski
One of the core XP practices is having a Customer Team Member. It means that development teams have access to the newest information from the customer's side and they know about all changes in the requirements very quickly. Having on-site customer (or customer proxy for commercial products with lots of potential customers) ensures that requests change informally, the process becomes flexible, and saves the cost of formal overhead.

In this post I would like to take another look at this practice. I would like to share with you my thoughts why having a Customer Team Member can help the development team win together with their customer. And I would like to take a "social" view on this practice.

Customer knows better
Some developers say "It would be better if the software wasn't made for the customers - we wouldn't have any change requests then and we wouldn't have to reimplement once delivered features". Good point, however in this case we wouldn't earn any money because no customer = no money.

XP is very clear about customers - customer should be a team member. XP says that the development team is able to consult with them all unknowns just-in-time and they don't have to assume anything or wait for their response (sometimes quite long which can result in development blockage).

Customer as a team member is very helpful - as I wrote earlier, communication is much faster and efficient as it is mostly informal. If a developer, or tester or someone else from the development team has some questions he/she goes directly to the Customer and gets the first-hand information instantly. No waiting - no wasting - no assumptions - Customer knows better.

"Social" aspect
My colleague who I worked with for last couple of years used to tell his best experience with Customer Team Member from his previous job. The project's goal was to deliver some software for the civil aircraft cockpit and the main users of this software were airline pilots. Airline pilots were the Customers.

My colleague worked for the whole project closely with Customer according to the XP practices and always says that this project was the most successful in this company. And I have to mention that the company was quite big - actually it was one of the biggest airlines in the World.

When I ask him why it was such a big success one of his main points is that when the team worked together with pilots they felt responsible for the project. They felt responsible for project's successes and failures - they were involved in the development process thus it was their product. They couldn't blame the team - they were the team!
More so, they saw how hard developers worked and that they weren't spending their time on drinking coffee and talking to each other. Pilots really appreciated the work developers were doing - they saw it, they were co-builders of the product. Customer Team Member = involvement, ownership and trust.

Customer proxy works well too
Leaving my colleague's example I have my own. I'm now working on the web GUI application for the XML-based backend and my "customer proxy" is a product definition (PD) team (my customer should be marketing directly but I don't set the rules here). They are supposed to know everything about the project - I mean requirements. To be honest it should be transparent for us as a development team who they are - they act as the Customer for us and they are on-site.

I noticed that we are the first team that works so closely with PD team but I see huge advantages. Actually I see the same advantages I was told about with airline pilots. PD sees how we work, they are involved in the development process, they know about our problems and we can adjust some requirements to the technical constraints on the fly without the overkill process of changing the documentation first.
PD team really appreciates work we do and they feel responsible for the project - it's not like "We give you the specification and now it's your business to make it work". They are helping us in adjusting the specification - but this is because we communicate them all our problems and we involve them in our development process.

It really works!

Just do it!
I hope I expressed the main points in just few words - it is very very important aspect of Customer Team Member (IMO).

And what should you do when you have problems in having an on-site customer? Robert C. Martin in his book "Agile Software Development, Principles, Patterns, and Practices" answers this question - just have one.

In practice it can be more difficult than that but it will pay off - you will win this together. Try to convince your Customer to work with you - if you succeed you will not regret it (will you?).

Do you have any experiences with Customer Team Member? Do you find it useful or useless? How do you manage to work with your customers?
Please share your opinions here.

Originally published on AgileSoftwareDevelopment.com

Wednesday, November 19, 2008

Seven Principles of Lean Software Development - Defer Commitment

Picture courtesy of _fabrizio_@flickr
No matter who you are, where you live and what your job is you have to make decisions. Some decisions are easier, some more difficult (e.g. which way do you want to go on the crossroad with traffic lights from the picture?). But why making decisions is hard? When you make a decision, how do you know it is the right one? What information (if any) you have to posses to make the right decision?

This problem can be referred as "Defer Commitment" principle. Very briefly it tells you to make the decision in the last possible moment when you have enough information to be sure you are going in the right direction. It doesn't tell to you to procrastinate - NOT AT ALL! It's a wrong thinking. It only tells you that you have to wait and collect the data and as soon as you have enough information, make the decision.

In this post I will try to explain "Defer Commitment" principle from "Implementing Lean Software Development - from Concept to Cash" book.

Schedule Irreversible Decisions at the Last Responsible Moment


You have to "abolish the notion that it is a good practice to start development with a complete specification" - basically They Aren't Gonna Read It.

I will give you a non-technical example (I think it's very popular but I will refactor it for my needs). Last year I was on my honeymoon in Spain - before going there I and my wife made a "big picture" plan what we want to see. We knew we were going there for three weeks and we were able to roughly assess how many places we are able to visit (in a decent pace - not travel-agency-rush-style). But we didn't have a full specification like: on Monday we are in Barcelona, Tuesday in Teruel, Wednesday in Madrid, etc. We just knew when we arrive to Spain, that we start visiting from Barcelona, when we have our flight back and what we want to see.

After few days in Barcelona we took a car and drove along the Spain to visit the rest of this amazing country. And we were planning our trip day after day - sometimes it was a bit stressful but we did it. We saw more than we planned and we had a really GREAT fun doing it. We were not attached to the plan - and I know we would have many problems with the plan because I made one just in case :) We wouldn't be able to see some places because we didn't know about many Spanish specifics - we learned them during the trip and we were able to adapt in an agile way.

The same is with software: "concurrent development saves money, it saves time, it produces the best results, it allows you to make decisions based on the most current data". You should know where you want to go but you don't know the road very well. You will be discovering it day after day - the most important thing is to keep the right direction. You don't necessarily have to drive highways all the time - maybe you should sometimes go with rutted roads - it can be faster and you may "see" and learn more things.

Break Dependencies


If you are worried about the dependencies of different components of your software - break them. Your components should be coupled as loosely as possible to enable implementation in any order. Of course some components will depend on other but it is often useful to rethink the architecture and accept dependencies only when there is no other sensible option.

Sometimes it would be useful to move some pieces of software from one component to another in order to remove dependencies. It's a very instructive exercise - you will merge few components in one or split one big component into smaller ones removing number of dependencies. Don't be afraid of doing this - you have REFACTORING (watch out - there are two links), right? But do it only when you arrive to the point you are sure you need it.

Loosely coupled components will pay off - you will be able to implement them simultaneously, thus you will deliver the whole product faster and your components will be probably reusable and ready to use in other projects.

Maintain Options


Good (but not always cheap) thing is to develop multiple solutions for all critical decisions and see which one works best. It can be sometimes hard, expensive and time consuming but you should decide what is cheaper in the long run. Robert Harris in his novel "Pompeii" wrote this: "What was leadership, after all, but the blind choice of one route over another and the confident pretence that the decision was based on reason". Do you want your decisions to be blind choices? If not you should invest some time and money in understanding the impact of each critical decision you have to make.

For all other (non-critical) decisions you should keep your code change tolerant. Remember that "change is the only constant". Make your code ready for changes - easy changes, and don't hesitate to change it.

Defer Commitment


I hope pieces of advice given above will make it easy to understand "Defer Commitment" principle. If you need more detailed description with more examples and more sophisticated explanation you should definitely go to "Implementing Lean Software Development - from Concept to Cash" book.

PS. Three principles described earlier can be found here:
  1. Respect People

  2. Deliver Fast

  3. Optimize the Whole



Originally published on AgileSoftwareDevelopment.com

Monday, November 17, 2008

Combining Callable or Runnable with Future and FutureTask

Picture courtesy of markhillary@flickr
In this part of the Java concurrency tutorial I will present differences between Runnable and Callable interfaces as well as when and how to use Future interface and FutureTask class. As a side-effect of this "lesson" I will present how to use ExecutorService.

I will present all of this on a real example where I "parallelize" a sequential algorithm in order to utilize more resources and to get better performance.

To make it as simple as possible I'm using very basic requirements. I'm implementing a Java class that goes through the predefined list of web pages (URLs) and counts the number of bytes for each resource - primitive crawler (without analysing the content). This class has to sum up all the results and display total number of bytes read. It also has to display total time spent on this task. Here is the code for the test class that uses Callable as a worker that reads the web page:

package futures;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test {

public static void main(String[] args)
throws InterruptedException, ExecutionException {

@SuppressWarnings("serial")
List<String> urls = new ArrayList<String>() {{
add("http://www.java2jee.blogspot.com");
add("http://www.yahoo.com");
add("http://www.msdn.com");
add("http://c2.com/xp/ExtremeProgrammingRoadmap.html");
add("http://apache.org/");
add("http://sourceforge.net/");
}};
List<Future<Integer>> futures =
new ArrayList<Future<Integer>>(urls.size());

final ExecutorService service =
Executors.newFixedThreadPool(1);

try {
long start = System.nanoTime();
for (String url : urls) {
futures.add(service.submit(new CallableExample(url)));
}

long result = 0;
for (Future<Integer> future : futures) {
result += future.get();
}
System.out.println("\nTotal bytes: " + result);
System.out.println("Total time: "
+ (System.nanoTime() - start) / 1000000
+ "ms");
} finally {
service.shutdown();
}
}
}

and the "worker" class follows:

package futures;

import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.URL;
import java.util.concurrent.Callable;

class CallableExample implements Callable<Integer> {
private final String currentUrl;

CallableExample(String currentUrl) {
this.currentUrl = currentUrl;
}

public Integer call() throws Exception {
int result = 0;
URL url = new URL(currentUrl);
LineNumberReader in =
new LineNumberReader(
new InputStreamReader(url.openStream()));

try {
String line = null;
while ((line = in.readLine()) != null) {
result += line.length();
}
} finally {
in.close();
}

System.out.println(currentUrl + " has " + result + " bytes");
return result;
}
}

And now a bit of explanation. Following line service.submit(new CallableExample(url)) submits new task to the Executor Service (created earlier) that will be invoked as soon as any thread in the pool is available. The submit(...) method returns a Future which in turn is added to the task list futures. After submitting all the tasks this program iterates over each previously submitted Future, gets the result and adds it the overall result variable result one by one. Future's get() method blocks execution of the program until the result is available and then returns the value (Integer in this example). Eventually this program shows the summary. Simple :)

As you can see in the Test class there is this line final ExecutorService service = Executors.newFixedThreadPool(1); that creates tread pool of size 1. It means that all the web pages will be visited sequentially one by one. Try to experiment with this parameter and see with what value you get the best results (on my machine thread pool of size 3 works pretty good and increasing this number more does not help).

With 3 threads each thread takes one web page, loads it and checks the number of bytes. As you can see we gained a lot by "parallelizing" such simple application. And this is the power of concurrent programming. Using simple mechanisms brought in Java 5 your applications can be more efficient.

Below I presented the same "worker" functionality as above but this time I'm implementing Runnable interface

package futures;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.MalformedURLException;
import java.net.URL;

class RunnableExample implements Runnable {

private String currentUrl;
private int result = -1;

RunnableExample(String currentUrl) {
this.currentUrl = currentUrl;
}

public void run() {
int result = 0;
URL url = null;
LineNumberReader in = null;
try {
url = new URL(currentUrl);
in = new LineNumberReader(
new InputStreamReader(url.openStream()));

String line = null;
while ((line = in.readLine()) != null) {
result += line.length();
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
} catch (IOException e) {
throw new IllegalStateException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}

System.out.println(currentUrl + " has " + result + " bytes");
this.result = result;
}

int getResult() {
return result;
}
}

In order to change the "worker" class you have to modify this line of code: futures.add(service.submit(new CallableExample(url))) into this one: futures.add(service.submit(new RunnableExample(url)), 0). It will not work as the previous example i.e. get() method will always return 0 instead of the number of bytes read by the task. I will leave the solution to this problem as an exercise for you dear readers. You will see that using Runnable interface is somewhat obsolete and can be pain in the a**.

I postponed the subject of FutureTask to the end. This class is considered by me as a helper class and will help you in many situations where you want to use Java 5 facilities, namely Future and your legacy Java code (or 3rd party components) accepts only Runnable interface. FutureTask implements both interfaces in question and you can treat is as a Runnable or Callable depending on the context or library capabilities. For more information plese refer to JDK documentation.

I hope this article helps you in understanding core Java concurrency components described above. If you find it interesting and useful or you have some ideas how it could be improved your feedback is more than welcome.

Friday, November 14, 2008

Video tutorial: Remote debugging of Java web applications in Apache Tomcat and JBoss

In this four minute tutorial I'm presenting how to remotely debug Java web applications in Apache Tomcat and JBoss containers. This tutorial may be useful if you deployed your application on the remote server and want to debug it in this particular environment. IMPORTANT: remember that your Java application HAS to be compiled with enabled debug information, otherwise you will not be able to debug it.
Remember: to start Apache Tomcat in the debug mode type this (on Windows):
set JPDA_ADDRESS=8000
set JPDA_TRANSPORT=dt_socket
catalina jpda run
on Linux you have to set environment variables using export command.
To enable remote debugging on JBoss server type this:
set JAVA_OPTS=-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8001,suspend=n
run <options>

More information on this subject can be found here:

Do you find this tutorial useful, interesting, fantastic or maybe boring and crappy? Please share your opinions in the comments zone.

Wednesday, November 12, 2008

Video tutorial: Test Driven Development with Mock Objects

In this eleven minute tutorial I'm presenting TDD with mocking technique using JUnit 4.x and EasyMock library. This is more advanced example of Test Driven Development - video tutorial on basics can be downloaded from here: Test Driven Development in practice.

Source code for this tutorial can be downloaded here (you can find also Eclipse project files in this bundle, so it's easy to import the project directly to your IDE - NetBeans users have to create a new project and add relevant classpath changes). Note that external.jar was built with Java 6 and thus you have to use at least JDK version 6 to be able to compile and run the example.



Enjoy and comment the video if you find it useful or useless. I'm really curious what you think about the video as well as about the mocking technique in general.

Originally published on AgileSoftwareDevelopment.com

Monday, November 10, 2008

Couple of book reviews (part 3)

It's been some time since I published my previous books review but I've been reading - that's for sure. Here is the list of books I've read since August:



I's been some time since I finished this book, therefore my short review is based on quite stale memory :) This book is great and if you want to familiarize yourself with the "Lean" theory you should definitely read it. This book will help you understand why lean and agile methods work and how pioneers in this field implemented them in the real projects. You will learn about Seven Principles of Lean Software Development an get to know how to put them into practice in your company.

This book is full of great examples and pieces of advice you should take seriously. Sometimes it becomes boring but all in all it is a great position you should have in your library.



AFAB - Absolutely Fu**ing Amazing Book! I loved the first edition of this book and I really really waited for the second edition covering Java 5 features. I am not disappointed - this book is ABSOLUTELY FU**ING GREAT! And I'm not exaggerating. Every Java developer has to have this book at hand. If you don't use "items" presented in this book you cannot call yourself good Java developer.

Joshua Bloch presents Java language in a fantastic way, he shows common problems and easy (not always) ways to solve them.
I use many of his pieces of advice every day and I see my Java code is simpler, cleaner and works better. And recently I find myself referring to this book when I encounter a wall and I cannot jump over it - this book helps me in, say 80% of the time.
An finally if you want to prepare yourself to the Sun Certified Java Programmer exam you will be prepared in 90% after reading this book. You will just need to cover some examination tricks with other resources (BTW. it took me two days).

AFAB!



This book disappointed me - it is my first and very important statement about this book. It starts with the "big bang" - no introduction, no description - just FIT. This is a really good definite guide to the FIT Framework and FitNesse but it lacks simple and concise "big picture" description. FIT seems to be very complicated to both developers and business people but in fact it is not (at least I believe it is not).
I see a big big potential in FIT but this book doesn't sell it very well. And from the developer's point of view FIT tests are not object oriented and it hurts (for example tests of many tables in one when you have to "store" one fixture in the static field and access this static field from another class - ugly!). Also creating custom forms is a nightmare (the invoice example) - if you move some fields or modify simple layout of your invoice (it happens, right?) you will break everything - maybe this is the expected result?

Anyway - if you want to know what FIT is and then use it, this book is for you. But don't expect clear and concise explanation of what FIT is. This is rather too technical book for business analysts and too "null" (I used "null" because I can't even find relevant adjective) book for developers.

To finish with a good accent - if you want to use FIT and need details, this book will work fine. This is a definite guide for FIT.

PS. You may find all the previous reviews here.

Friday, November 07, 2008

Happy Birthday...

Picture courtesy of chidorian@flickr
... to the "From Java to Java EE" blog.

It's been two years since I started blogging and I find this period quite successful. I posted almost one hundred posts to this blog (some of them were longer, some shorter, some more interesting some not so much) and I'm pretty proud of it. And this year 2008 is the most successful ever as I already "produced" more posts than in 2006 and 2007 summed together. FeedBurner also shows increasing number of permanent readers - it's very nice.

Let's hope I will keep the decent pace of at least one interesting post per week.

Thank you readers and let's hope to the bright future of this blog!

Happy Birthday to the "From Java to Java EE"!

Wednesday, November 05, 2008

Agile Success Story: interview on how Agile movement helps company to grow and succeed

Picture courtesy of M. Keefe@flickr
Last week I had a great fun and honour to interview Janusz Gorycki who is a partner and a team manager in an Agile Software Development company - Spartez. Janusz is also the author of the open-source screen capture and painting utility for Windows named Mazio.

In this interview I'm asking Janusz about how they founded their company and how agile movement helped them achieve success. I'm also asking how they see their agility, what problems they have and how they deal with them. Janusz also answers why you can be CMMI-compliant using agile methodologies and recommends steps by which you can start applying Agile practices in your company.

Is this interview about yet another agile company? Not really - Spartez is an extraordinary company composed of ordinary engineers who were not afraid of making their dreams come true. Their determination, team work, a bit of luck and an extreme agile spirit helped them be and work together and become successful. This is a real-life example how cross-functional team, where each member is an expert in some areas, is able to deliver any software to any customer. And how do I know this? I used to be a part of this team at Intel and know this team as well as each member pretty well, however I'm not affiliated with them anymore in any way.

If you are interested in getting to know how they started, what and how they do now, this article is for you. Maybe you will follow their dreams and ideas - I think it's worth.

List of questions:


  1. As far as I know you worked together as a team at Intel which is huge corporation. I also know that you were not using Agile from the beginning. So, how did this all start?

  2. What are you working on now and how Agile methodology helps you?

  3. What Agile techniques you use (Scrum, XP, etc.)? What principles and activities you utilize and which one you abandon? Why? Don't they work for you or you consider them obsolete/unnecessary/unimportant?

  4. What tools do you use? Can you be Agile without them? What do you gain/lose using tools?

  5. Do you want to tell our readers something more about your development process? What makes you successful, what would you like to recommend trying?

  6. What are, in your opinion, three most important things that make Agile methodologies successful?

  7. What are three most important problems you encounter with Agile techniques? I won't believe it's always cool and problemless. How do you cope with them?

  8. You are familiar with CMMI as well and worked in huge corporations. Can you accommodate CMMI and Agile?

  9. Was it good decision to start thinking Agile? What did you gain as people, engineers and team?

  10. How would you encourage other companies and teams to start investing their time in Agile methodologies?

Przemysław Bielicki: As far as I know you worked together as a team at Intel which is huge corporation. I also know that you were not using Agile from the beginning. So, how did this all start?


Janusz Gorycki (Spartez): Yes, we have started our work together as a team at Intel's IT. The team consisted mostly of Intel newcomers and I was a long-time Intel employee (more than 10 years in one company, but in a different division), so I got appointed as their manager. Very soon after the team was formed, it became apparent that traditional software development methods, which I was used to while working at my former team, and which more-less worked acceptably well there, were hopelessly inefficient, unpredictable and very costly when applied to the internal IT environment. It was not uncommon for a software project at that organization to be more than a year late, and during that time deliver hardly any business value at all.

So we have started, at first in the "stealth mode" (without telling any higher-ups), to look for more efficient alternatives. Agile methods were, at least partially, known to some members of the team, so we decided to try them out. The productivity boost just from time-boxing our development and defining exactly what we will work on during each iteration was immediate and obvious. And as far as I remember, we have initially decided on a three-month iteration cycle - unbelievably long by normal agile standards. Encouraged by this success, we tried more and more practices.

But the real, no holds barred, use of agile methods, started after we all left Intel and created our own company - Spartez. We basically established the company as a place with agile spirit from the very beginning.

Back to list of questions

PB: What are you working on now and how Agile methodology helps you?


JG: We were able to launch Spartez, because we have managed to find a strategic partner - a company from Sydney, called Atlassian - the makers of excellent software such as JIRA and Confluence. Most of the software we develop is written for them and we are also resellers of their products. The main software product we are working on, and actually 100% own its development, is an open-source IDE Connector, integrating Atlassian web-based software into IDEs such as IntelliJ IDEA and Eclipse.

The development of this tool is done as a series of 2-week-long Scrum sprints, with almost each sprint's results actually released publicly, with downloadable and installable binaries. Each sprint delivers an increment of value to users of the Connector. I don't think we would be able to successfully launch Spartez and remain in operation for a year, without any initial funding whatsoever, were it not for agile methods - Atlassian folks were astonished that we were actually able to release a usable piece of software after just two weeks of work. Obviously, compared to where we are now, the functionality of the release was extremely limited and primitive, but the point was - we were able to prove to our customers from the very beginning that their investment was justified, because we are able to deliver on our promises.

Back to list of questions

PB: What Agile techniques you use (Scrum, XP, etc.)? What principles and activities you utilize and which one you abandon? Why? Don't they work for you or you consider them obsolete/unnecessary/unimportant?


JG: Sometimes we do get tired of this or that practice, becuase the downside of these practices is that they require quite a lot of discipline. The funny thing is, we get in trouble each and every time we abandon or do too little of some practice.

An example: we have agreed to release (internally) the new version of the software every second Thursday, dogfood it for a bit and launch a public version the next Monday morning. It so happened a couple of times, that we told ourselves "let's not release on Thursday because we need to finish this or that story". That proved to be a mistake every time we did this. By breaking the release cycle, we were forced to shorten a subsequent iteration and not only we delivered less functionality the next time around, but we broke our velocity measurement and lost control over one of the most vital metrics we had at our disposal.


Another example - unfortunately we don't unit test enough. Sometimes unit testing some functionality is prohibitively difficult when you write a plugin for some other software (like IDE), because there is no way to properly mock or stub some piece of code that you depend on. Well, we could probably try to mock them, but we decided that we would not, as we would have to rewrite half of the IDE. This has immediate negative consequence on the quality of the code. There is no doubt that the pieces of code that are unit tested (because they are not tied to the IDE), are of much better quality and easier to extend and maintain, than the pieces of code that are not unit tested. We are aware of this problem and we are long overdue addressing it adequately.

I can honestly say that all of the agile practices are important and they represent a coherent system. Abandoning some XP or Scrum practice may sometimes be necessary due to unforeseen circumstances, but I would recommend sticking to them as much as possible. Therefore I will not try to list the ones that are of more or less use.

Back to list of questions

PB: What tools do you use? Can you be Agile without them? What do you gain/lose using tools?


JG: This is the beauty of it - you don't really need sophisticated tools to successfully do agile development. At Intel, we have started with a cork board, sticky notes, scissors and pencil. And it turns out, these remain to be our most important tools to this day. This, a version control system (I would recommend SVN in most cases), a bug tracker and a continuous integration server are the only crucial tools you will need.

You should use other software tools only after you know which aspect of the agile software development you want to optimize in your particular situation. We are in a very lucky situation, where Atlassian has supplied us with an excellent software tools that nicely compliment each other. We use JIRA bug tracker for planning, tracking and bug reporting, Bamboo build server for continuous integration, Confluence Wiki for knowledge sharing, and Crucible for source code reviews.

Other tools? I would recommend getting the largest LCD screen you can buy (and they are dirt-cheap these days), computer with enough juice in its CPU to not frustrate you, plenty of RAM and a comfortable chair.

Some folks also like IDEs - like the IntelliJ IDEA that we happen to use. And I would agree that they do help, but I am tempted to also say that they sometimes help you too much - and instead of spending your time thinking about your design - you Control-space through your code, often times making it overly bloated and unnecessarily spaghetti-like. I sort of long for the days when you were limited to just bash and emacs (vi users - I am sorry, your way is wrong, but you will see the light some day). Not because I am a ludditte, but because in the absence of the powerful IDE, you have to stretch your mind more to make the code simple, elegant and concise.

Back to list of questions

PB: Do you want to tell our readers something more about your development process? What makes you successful, what would you like to recommend trying?


JG: Before I try to describe what we do, it is important to understand that these days, the eight of us work on at least four different projects. This means that some teams are actually one-person teams. And such small teams actually do not need any formal process - after all, the only reason for the existence of a process is communication - and if you are alone in what you do, you don't need much communicating. Except of course with your customers.

For the bigger projects, we start with a release planning session, during which we size all user stories that we have been able to gather from the customer. The stories are already prioritized by the product owner in some way - unfortunately sometimes only roughly. We play planning poker for each story and after the session we enter the results into JIRA.

After that, every two weeks (on Monday) comes an iteration planning session. During this session we commit to a subset of stories, trying to pick the ones from the top of the backlog, but sometimes for architectural or other reasons we also pick stories form the middle. Obviously, we also have bugs - and they tend to be quite hard to properly size, so in their case there is a lot of guessing involved sometimes. So what we do is try to have at least a 50-50 distribution of bugs and user stories for every iteration.

Then, every day we do daily stand-up - 10am sharp. We try hard to make it no longer than 15 minutes, but sometimes we fail (and this is all my fault as I lead these meetings).

Sprint demos are quite problematic in our case - our customer is in Australia and it is not realistic to actually do live presentation. What happens instead is we try to educate our product owner (who is in Sydney) what we delivered - he just looks into JIRA and he can monitor what's going on. He would then do demos for the end users (who are at this moment mostly developers in the Sydney office).

How we do actual development? That sort of depends on the task at hand. Sometimes we pair-program. Actually we should do much more of it than we do now, but this is a pretty intensive activity and therefore not everybody naturally chooses it. We have a Bamboo continuous integration server checking our code, so all of our commits get sanity checks, the code is always compilable and unit tested. For the more problematic, tricky and complicated code we do code reviews - using the Crucible tool. We do try to "dogfood" our own product as much as possible - if the required functionality is available (even if it has bugs), we try to do as much interactions with the tools using the IDE Connector that we are developing. That way, we know if we like the UI that we have just created and we are able to detect bugs before they hit the customer.

Would I recommend our ways to everybody? The elements of it - yes, all of them. The whole process? Not necessarily. In reality, you should use a process and methods that suits your team. Ours attempts to be optimal for us. It will probably not be optimal for you.

Back to list of questions

PB: What are, in your opinion, three most important things that make Agile methodologies successful?


JG: Let's tweak this question and answer this one: "Why are agile methods better than non-agile ones?" Let's try to answer that question. I would begin by this observation: software development is a chaotic process. By "chaotic" I mean "the one where slight modification of input parameters causes huge changes to the results" (I guess I could give a lot of examples here, but I don't want to make this interview even longer than it is now). The only way to control a chaotic process that we know of is by using empirical methods. Agile development give you means for empirical process control. You get your process checkpoints every day, every two weeks, every release. You can actually measure (as opposed to just guessing) how effective you are and what your real (as opposed to perceived) pace is. There is no "perpetual 80% done" syndrome in agile development. You can actually tell how much you have done so far and be certain that you are "done" working on something.

Second, agile software development give your customers better control over how they spend their money. They get results fast, they can check at any moment the health of the project they invested in, and they can stop the project at any moment when they determine that the investment does no longer brings expected results. Usually, 20% of the features give your customer 80% of satisfaction. With agile methods, you can deliver these 20% in 20% time, instead of being 2 years too late.

Third, agile methods give your team frequent and regular small successes - you release your software every second week or so, somebody is using it, giving you feedback, and the feedback is very likely to be positive, as you are building the software to exact specs of the ones you are working for. This builds confidence, enthusiasm and sense of working on something useful.

Back to list of questions

PB: What are three most important problems you encounter with Agile techniques? I won't believe it's always cool and problemless. How do you cope with them?



JG: The problem with agile methods is that they require much more discipline than "traditional" ones. The simplicity of the process definitions and "obviousness" of the practices is very deceptive. Agile methods require you to keep your pace day in and day out. There is no "quiet period" after a "death march". At first that may be problematic to some people. You will have to be effective as a developer, and your effectiveness is easily verifiable, every day of the year. The good news is that once you get accustomed to the routine, it becomes natural. Moreover, once you prove to yourself that you are able to deliver at an acceptable pace, your confidence improves. The question is - what if you _are not_ able to deliver at an acceptable pace? Well - XP has built-in mechanism for improving skills of team members, the best of which is without a doubt pair programming. But you have to be aware of the skills of everybody and react to people's deficiencies as you discover them. This is not always a pleasant exercise.

More dangerous than the first threat is lack of feedback from your users. This will surely cause you to get derailed, as user feedback is of paramount importance. Agile team has to do everything that is in their powers to get feedback. This is not only the responsibility of the ScrumMaster and the product owner - everybody on the team has to be aware that the feedback loop has to be maintained and supported by all means possible.

Third threat is lack of flexibility. Agile processes are meant to be improved. You are supposed to tweak, modify and fix them to your liking and to the precise needs of your team and its customers. There are sets of "best known methods" in Scrum or XP, but they are just that - "best known methods" and not a bible. It is important to understand that there are no "sacred cows". The process itself must not become a holy grail - it is just a means to achieve a goal and nothing more than that. If it makes sense to break the rules that you learned at your ScrumMaster training, go ahead and break them. Just be aware that you are breaking them and that you are doing it for a reason.

Back to list of questions

PB: You are familiar with CMMI as well and worked in huge corporations. Can you accommodate CMMI and Agile?



JG: I have somewhat mixed opinion about CMMI. On the one hand, the principles of CMMI are actually great - the central goal of striving for ordered, dynamic process, that has built-in mechanisms for self-improvement is something that I like, and which is also exactly what the agile methods are all about. On the the other hand, I am yet to see an implementation of CMMI that is not hopelessly heavyweight, overly complicated and and that is not making your life as developer miserable.

I suppose the reason for this is two-fold:

First, the only successful processes are ones that are built bottom-up, as a response of actual, painful needs development teams, designed and tailored by the teams themselves and modifiable by the actual users, without having to go through the huge bureaucratic hassles. CMMI however, is unfortunately usually introduced from top down, at the request of the higher management - more often than not quite isolated from, and unaware of, the gory details of day to day development work.

Second, the successful process has to be simple, intuitive and so natural that you would naturally resort to it when working under stress. Unfortunately, all CMMI implementations I have seen so far are heavy, complicated and impossible to fit in the head of a mere human. So what people tend to do is work around the complicated process in many cases, giving the false impression that they follow it, while in reality their real process is quite different from the "CMMI-defined" one. I have seen this evolution from "let's follow our CMMI process to the letter" to "let's pretend to follow it and get stuff done somehow, because our defined process does not actually work" happen a lot.

Having said that - I think agile methods can be basis of a complete CMMI implementation (up to level 5, no less). Just notice that some of the core agile principles are precise, empirical measurements (story size estimations, velocity), formal contracts between stakeholders (prioritized backlog) as well as built-in self-healing and self-improvement of the process (Scrum demos, retrospectives, daily stand-ups, pair programming).

Back to list of questions

PB: Was it good decision to start thinking Agile? What did you gain as people, engineers and team?


JG: I think it was the best decision that we as a team have ever made. The decision actually started us as an independent, and so far quite successful company - something that many of us dreamed of but before we met, had no guts to actually decide to do. Agile methods gave us discipline, they allowed us to easily share knowledge, improve ourselves, understand what we are capable of and what are our realistic and objectively measurable abilities. This is not to say that we are perfect - far from it, the team seems to be in a constant state of internal turmoil - and I think this is a good thing. But we seem to be, as a team and as a company, in control of our lives and we are able to "make our own luck" in stead of totally depending on the decision of others.

Back to list of questions

PB: How would you encourage other companies and teams to start investing their time in Agile methodologies?


JG: I would advise to start small. Don't make a "big bang jump" to an all-agile software shop. For example, it took us about three years of incremental improvements to get to where we are now, and we are still very far from perfect. Stay cool, stay calm, have guts and courage to try new things, pick and choose whatever seems to make natural sense.

Also - do not try to spend most of your money on fancy tools. Like I said - at first, paper, pencil and cork board will be all you need. After you understand what it is that you need, you will know what fancy tools to buy. And I hope you will turn to us to sell them to you, because we sell good stuff.

Back to list of questions

PB: Thank you very much for your time


Few facts about Spartez


Website: spartez.com
Location: Gdańsk, Poland
Operational range: global (currently working with customers in Australia, USA and Europe)
Areas of development: IT systems integration (B2B, SOA, middleware), aeronautics and GIS, telecommunication, low-level and embedded systems in the following technologies Java, C# (.NET), C++, C, assembler

Originally published on AgileSoftwareDevelopment.com

Monday, November 03, 2008

Video Tutorial on "Detecting and debugging deadlocks"

In this three minute tutorial I'm presenting how to detect and debug Java deadlocks in runtime while having access to the application console. Code for the example can be copy-pasted from the previous post. Remember: to dump the thread stack you have to press Ctrl+Break on Windows and Ctrl+\ on Linux.


More information on this subject can be found here:

Please share your opinions in the comments zone.

Sunday, November 02, 2008

Cisco's $100,000 Developer Contest

A Cisco's PR person contacted me to share the information about the developer contest and I found it interesting enough to share it with you - readers.

The point is to develop an application for the Cisco's router and the cool part is that it runs Linux and supports Java, Perl and even Python. If you are lucky to propose one of the most interesting concepts, you get 90 days for the actual implementation and can win up to $50 000. You can find more information at http://cisco.com/go/thinkinside and http://youtube.com/watch?v=RrqTv3MkIHI

Have fun!

P.S. I am not affiliated with Cisco in any monetary way

Saturday, November 01, 2008

I'm changing my given name

It is an era of UTF-8 and there is no reason for me to hide my real given name which is Przemysław not Przemyslaw. I'm proud of the polish letter ł in my name and from now on I'm changing my name in all Internet accounts I have to the original one.
I don't care if someone cannot pronounce my name - I have to learn french, german, spanish, italian, etc. names and I do it so you have to learn how to pronounce my name too (it's something like Pshemyswav).

Cheers!

Friday, October 31, 2008

Builder-style setters for Java

Setters idiom in Java is an evil and I hate it. And I don't hate it because you have to invoke setXXX methods multiple times when you have to set many fields. The most annoying thing for me is that you can only set one field in a line. This is because setter method return this stupid void. Here is the example:

public class Car {
private int maxSpeed;
// remainder omitted

public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
// remainder omitted
}
so my code using the Car class will look like this:

Car car = new Car();
car.setMaxSpeed(210);
car.setSpeedUnit("km/h");
car.setLength(5);
// remainder omitted
I have an idea how the life of the developers can be made easier using builder-style setters "pattern". Here is the new BETTER Car class:

public class Car {
private int maxSpeed;
private String speedUnit;
// remainder omitted

public Car setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
return this;
}

public Car setSpeedUnit(String speedUnit) {
this.speedUnit = speedUnit;
return this;
}
// remainder omitted
}
I could instantiate and initialize my Car object in one line (maybe wrapped but still one line of code):

Car car = new Car()
.setMaxSpeed(210)
.setSpeedUnit("km/h")
.setLength(5)
...
What do you think? Isn't it much easier? Of course if you extend Car class it becomes more tricky as you have to repeat all the setter methods like this:

public class Truck extends Car {
private int capacity;
private String capacityUnit;
// remainder omitted

@Override
public Truck setMaxSpeed(int maxSpeed) {
super.setMaxSpeed(maxSpeed);
return this;
}

@Override
public Truck setSpeedUnit(String speedUnit) {
super.setSpeedUnit(speedUnit);
return this;
}
// remainder omitted
}
But hey - who extends simple JavaBeans?

Maybe I can suggest this idea as a JSR-666 (there are two links :)? I'm curious what is your opinion about this idea. Please share your thoughts in the comments zone.

Thursday, October 30, 2008

Agile Software Development with Scrum (PDF)

I don't know what is the value of the presentation without the presenter talking about the details but anyway I'd like to share with you my work. I presented the following slides during technical evening for my current employer's engineers in June 2008. Here it is (PDF):



Enjoy!

Wednesday, October 29, 2008

Video tutorial: functional testing with Selenium IDE

In this tutorial I'm presenting Selenium IDE - a tool for recording and replaying functional tests of web based applications. I'm showing how to record a simple test, test for Ajax-enabled application and how to replay such tests in Firefox web browser. I'm not showing how to start Selenium tests from Continuous Integration server in this tutorial - this is a subject for separate post.

I tried to make this tutorial short yet valuable and I hope you will see great value in Selenium IDE tool which is an open-source and free for commercial use. With Selenium tests you are able to test your web applications from the user's perspective, not from the code perspective. This greatly simplifies the acceptance testing and lets you know about all problems as soon as they arise.
Selenium tests should be considered as complimentary testing to unit tests - the best idea is to combine them both to get the best results. Unit tests should test your code and Selenium tests should test features available for your users.

I hope you will like it.

Originally published on AgileSoftwareDevelopment.com

Wednesday, October 22, 2008

Premature optimization is the root of all evil - not only in the Agile world

Picture courtesy of gutter@flickr
I was just reading an excellent book by Josh Bloch, namely "Effective Java, Second Edition" and I was on the optimization subject when it happened. It was funny coincidence but I think it was just a sign for me to write this post.

It doesn't relate to the Agility in any way but it relates to the quality of software so it should be definitely published here. And it all started very innocently - from publishing blog post with the solution to some annoying problem.

In this post I will tell you how easily you can fall into really dangerous and ugly development problems starting optimizing your software too early. I hope you will like the story.

Start with the simplest possible solutions...


I've been reading "must-read" book for all Java developers, namely "Effective Java (2nd Edition)" by Josh Bloch and I was just reading "Optimize judiciously" chapter. In the same time I was doing some Java EE development and I encountered a problem with Struts2 file upload capabilities. I found a solution and posted it to my private blog: http://java2jee.blogspot.com/2008/09/solution-to-struts2-upload-file-error.html. "This has nothing to do with the optimization", you may think - and I thought the same but it's wrong assumption.

After few days I received a comment to this post from anonymous user with an "optimized solution". The author of this post wanted to optimize this line of Java code:

if (string.contains(
"the request was rejected because its size")) {
with this code:

public static Pattern REJECTED_FILE_SIZE_PATTERN
= Pattern.compile(".*reject.*size.*");
...
if (REJECTED_FILE_SIZE_PATTERN.matcher(string).matches()) {


I always considered myself as a seasoned Java developer (hopefully it is still true :) but after receiving this comment I was quite worried. "Why I'm not using regular expressions to check strings? Isn't it much faster", I thought. I was even thinking: "Maybe it's time to become a manager? - my Java/technical knowledge is deteriorating..."

"But hey! I will not let it go like this" - I thought. I wrote a simple Java program to test the performance of both solutions:

import java.util.regex.Pattern;

public class Test {
public static void main(String[] args) {
int count = 1000000;
Pattern p = Pattern.compile(".*reject.*size.*");
String matching = "the request was rejected because"
+ "its size (1234) some other text";

long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
if (matching.contains(
"the request was rejected because its size")) {
// do nothing
}
}
System.out.printf(
"contains() matching: %dms%n",
System.currentTimeMillis() - start);

start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
if (p.matcher(matching).matches()) {
// do nothing
}
}
System.out.printf(
"matches() matching: %dms%n",
System.currentTimeMillis() - start);
}
}
On my machine the standard contains() solution is 50 to 80 times faster than the solution with regexp matcher. What a disastrous effect this could have when applied in the whole application! I can't even imagine.

When I took a look at the contains() method implementation I saw that it operates on the char array (i.e. underlying array that creates the String object). It is fast! And it is the simplest and the most obvious method to call in this situation. It even makes the code more readable and tangible than with the regexp matcher. I see only the advantages.

The conclusion is simple: DON'T OPTIMIZE YOUR CODE AND USE THE SIMPLEST POSSIBLE SOLUTIONS - THEY WORK!

... and stay with them


Joshua Bloch cites these guys:

More computing sins are committed in the name of efficiency (not necessarily achieving it) than for any other single reason - including blind stupidity. (William A. Wulf)


We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. (Donald E. Knuth)


We follow two rules in the matter of optimization:
   Rule 1. Don't do it.
   Rule 2 (for experts only). Don't do it yet - that is, not until you have a perfecly clear and unoptimized solution.
(M.A. Jackson)

What else I can add? Actually, nothing. I just showed that each of the quotes above is true on the real example.

To rephrase Joshua Bloch: Never focus on optimizing your software. If you write good and logically structured code your software will be probably optimized by itself. Use well known, standard libraries and use the most basic features that meet your requirements - the optimization and quality will follow.

Do you have similar adventures with sub-optimal solutions? Maybe you disagree with me? I would gladly read your opinions.

Originally published on AgileSoftwareDevelopment.com