11/26/06

Key trends faced by Software Developers (2006)

I think that professional software developers of all callings (Java, .Net, C++, Ruby etc.) are facing five key trends at this point in time (Q4 2006). Some of these have been around for a while and continue to gain momentum (e.g. Agile methods) others are more recent (e.g. Web 2.0).

#5 Integration Beyond "Just" Web Services - SOA / ESB
This really took off in 2004 and is still chugging along quite nicely. Part "Marketecture" and part real promise, the concepts of SOA (Service-Oriented Architecture) and ESB (Enterprise Service Bus) are still selling well and are especially hot among consulting firms selling the latest and greatest thing (perhaps eclipsed only by Web 2.0)

Beyond this, other standards such as WSCI (Web Service Choreography Interface) and BPEL (Business Process Execution Language) are trying to bring SOA to the next level. The job market seems to indicate that SOA is where the action is at (based on keyword searches).

#4 Agile Methods
Having slowly gathered pace over the last 4-5 years, agile development methods and management practices (such as XP, Scrum, Crystal etc.) have gained a following and some acceptance among developers but the job market still doesn't seem to require any skills in it - a few hits on XP and Scrum.

#3 Cost-effectiveness
From the Eclipse IDE to Server-consolidation to outsourcing/offshoring to other open source components, developers are facing a push from the CIO/CTO office to reduce development costs. As of mid-2006 however, much of the "fat" has been squeezed out and management is realizing that offshoring has its own problems - however the cost concern remains. Many companies are also deciding to move their base of operations to less expensive parts of the country if not the world.

The job market influence comes down to a large number positions needing you to know lots of open source packages (e.g. Tomcat, Geronimo, Ant/Nant, Junit/NUnit, Eclipse, log4j etc.) as well as having experience working with some team-members in other sites (either near- or off-shore).

#2 Rich-Internet Applications & Web 2.0
Ajax, Rich-Internet Applications and Web 2.0 are *HOT* *HOT* *HOT*. Beyond creating user-focused sites with lots of Javascript ad some web services this really doesn't mean much in terms of revolutionary change - but it sounds cool to those in the CxO suites and consulting companies are happy to sell it (whatever it is).

However key aspects of Web 2.0 such as "users owning the data" will be hard for traditional brick-and-mortar S&P 500 companies to grasp or make useful!

That said the job market is starting to show interest in Ajax and certainly in Web Services.

#1 Open Source
Not really a big trend in-and-of itself - more a trend within trends, that is, open source cuts across all of the previous four trends and many others.
  • For SOA you've got the likes of ServiceMix
  • For ESB you've got Mule - both it and ServiceMix are gaining traction
  • For Agile development you've got JUnit for unit testing, CruiseControl for continuous integration etc.

  • as mentioned previously, open-source by definition, is cost effective and
  • many of the standard bearers of Web 2.0 are built on key open source components or platforms (e.g. Google is a big Linux shop, Wikipedia is built on PHP etc.)


What it all means for developers?
Each of these key trends also is at the heart of the never-ending "Hype vs. Actual Delivery" struggle. How can developers that want to drive real value to their customers do so in an ever-more effective manner and yet not oversell based on the hype generated by the media and companies with something to sell?

With many of the hyped technologies and processes, there is often a lot of real promise behind it, but there are no free lunches. So the key is to adopt and learn some (but not all) of the technologies over time . . . but which ones?

For developers the approach I recommend is to keep an eye on the headlines of software development news (e.g. use DZone for on-line or get a subs to SD Times for off-line) and watch for correlation with keywords in job postings (I highly recommend using Indeed for quick and comprehensive searches and you can also set up agents to email you matches). Between the two you'll start to see patterns emerge as key technologies come into the mainstream.

Right now, I figure that open source and web services are great places to start, and it's always a good bet to learn and get practice with as much Javascript as you can (Web 1.0 ain't going away anytime soon and Web 2.0 loves Javascript).

11/21/06

The Best Java and Software Engineering Web-sites (2006 rankings)

Here's list of my favorite Java and Software Engineering web-sites as of 2006. It's not all of the ones I visit, but these usually contain what I need and have the highest signal-to-noise ratio.
For my favorite blogs you can always check my blogroll in the right-hand-side div -->

GENERAL JAVA INFO
The Server Side http://www.theserverside.com/
DZone http://www.dzone.com/
Java.net http://java.net/
IBM Developerworks http://www-128.ibm.com/developerworks

GENERAL SOFTWARE ENGINEERING & ARCHITECTURE
IBM Developerworks http://www-128.ibm.com/developerworks

BEST PRACTICES AND HOW TO
Java Practices http://www.javapractices.com/index.cjp
Java Developer Almanac http://www.javaalmanac.com
Java Performance Tuning http://www.javaperformancetuning.com/

GOOD FOR JAVA Q&A
Java Ranch http://www.javaranch.com/
JGuru http://www.jguru.com/
Experts Exchange http://www.experts-exchange.com/

MAILING LISTS
Java Lobby http://www.javalobby.org/
IBM Developerworks http://www-128.ibm.com/developerworks
IBM / Rational Edge http://www-128.ibm.com/developerworks/rational/rationaledge/

JUST FOR FUN
It's so accurate, funny and sad - it's scary. Dilbert! http://dilbertblog.typepad.com/

Notably absent
- Apart from Developerworks and Rational Edge, there aren't too many great sites for general software architecture / software engineering practices. Any recommendations?
- After several years of searching I still haven't found a good site for general databases / data modeling / SQL etc. Any recommendations?

11/20/06

Java 5 - The Gems and the Duds

Java 5 is, in my opinion, the greatest incremental release of Java since Java 2 came on the scene - JDK 1.2 ,way back in the day (1998 or so).

I've been coding with Java 5 now for just six months and I just wanted to touch on some of the great things in Java 5 that, for the first time, make me want to tell Java developers to
upgrade NOW!

THE GEMS
1) Java.util.Concurrent


For those of us that write multi-threaded programs, this API is a god-send. I'm sad to say that I did not know about the existence of this library prior to it's inclusion in the JDK and wish I had, as it would have made my life so much easier (See oswego link)

When writing Multi-threaded programs you spend so much time writing code to
1) Create and maintain thread pools e.g. add new threads to handle increases in load
2) Block until threads have done something
3) Threads polling shared data structures (ouch synchronization issues!)
etc. etc.

There's also the nasty surprises that you hit when you realize that simple things, like incrementing an integer, are not guaranteed to be Atomic!

Now with things like Executors and Futures and also faster thread-safe collections (e.g. ConcurrentLinkedQueue), there's just a TON of fabulous stuff here.

Brian Goetz has written a load of great articles on the framework (not to mention Java Concurrency in Practice which he wrote with several others).
See for Example
Put JDK 1.5's Executors to Work for You also
Structuring Concurrent Applications in JDK 5.0 and
Executing Tasks in Threads

When put together, these pieces make it much easier to write multi-threaded applications, and best of all, it makes them easier to understand and helps reduce the appearance of nasty bugs that are very common to such inherently unpredictable programs.

2) Generics
I always had a love-hate relationship with Java Collections - the interfaces were so friendly and easy to use, but being one who loves strong and static typing, I hated passing around a java.util.List or Map without really knowing at compile time what objects might be lurking inside and might trip me up with a good ole ClassCastException at Runtime!

So the addition of Generics was a big plus.

3) CachedRowSet
Probably not as "on the radar" as #1 or #2 are the advances in JDBC 3.0 that are included in Java 5. In particular javax.sql.CachedRowSet.

In a nutshell "A CachedRowSet object is a container for rows of data that caches its rows in memory, which makes it possible to operate without always being connected to its data source. Further, it is a JavaBeansTM component and is scrollable, updatable, and serializable."

Finally we can pass a "ResultSet"-like object around between classes, between layers or between tiers. Then we can update it, delete rows, add beans etc. and then send it back to the database for "Syncing" up. Wow!

Also buried in JDBC 3.0 - the caching of prepared statements is a welcome addition. Anything that puts the onus on the Driver rather than the coder is a boon!

4) Annotations
Anything that makes J2EE programming easier is a boon (esp. less classes to write!)

THE DUDS
Well there's actually only one . . .
Autoboxing
There's really only one dud in Java 5 and that's autoboxing. Now I love the foreach loop, and removing boilerplate (casting) code is always a good thing. But introducing the possibility of more NullPointerExceptions is a tough price to pay.

See this ServerSide article for a good summary.

In the end I just configured my IDE (Eclipse) now to create an "Error" anytime it sees any boxing and unboxing conversions.

The key issue is, after 8+ years of Java programming and fixing several *NASTY* NPEs, I really didn't need my job doing NPE fixes to get any harder or more frequent :-(

TOO EARLY TO TELL
1) Varargs
Haven't really used Varargs in Java enough yet so it's too early to tell - looks like a positive but hopefully there's no landmine buried there like for Autoboxing!

2) Enums
In general I'm leaning towards liking Enums in Java but I have to really play with them a bit more before deciding. Java is an OO language and these are like Classes/Objects and yet not - so I'm not 100% sure of how they should be treated in practice. Probably some best practices will emerge!

In Conclusion
Sun and the JSR leads have done a really good job, the only pain being a new IDE setting, but the gains are fabulous. I look forward to more of the same in Java 6 (now open source eh!?)

HOLD THE PRESSES . . . .
Here's one I forgot to mention but also goes in the "Gems" section - now in the Thread class you have a method that will return a Map from a Thread object to an array of StackTraceElement objects. See Thread.getAllStackTraces() . What a really useful tool to aid in diagnostics / debugging.

11/14/06

Big Bad Architectural Smells - #2 Wrapping your logger

In the first of my "Big Bad Architectural Smells" series - "Roll your own ORM" the theme was basically that of "buy vs. build", or to be more precise "reuse-open-source vs. build".

The theme here is pretty much the same . . . . projects in which the logger was wrapped by a proprietary layer (build) versus just using the logger itself (reuse)

The first time I saw someone wrap log4j, I put it down to the inexperience of the lead developer and the architect and hey it was 2002 - was log4j really going to be around in a few years? What's this Open Source thing anyway? Is it a fad? It was understandable.

The second time I saw it, in 2004, - different team, different project - this time wrapping either log4j or Sun's own Logger, it became a moderate annoyance. Log4j was here to stay.

But the third time in 2005 took the biscuit. Someone actually wrapped Commons Logger. Now if you don't already know Commons Logger, its goal in life is that it is intended as "an ultra-thin bridge between different logging implementations". It's a wrapper itself!

Oh and then the implementation of this wrapper then basically bolted on a bunch of functionality that already existed in log4j (DB Appenders, JMS appenders etc.)! AAAGGGHHH!

In each of these cases they've added a whole bunch of code and gained no real net new functionality that was already there. In fact in several cases they lost some (by masking some of the amazing capabilities of log4j).

Now the motivation behind each of these choices was basically to insulate the application code from the underlying logging implementation- but really - are you *THAT* worried about decoupling your application from your logger?

There are usually so many other architecture or design issues to be resolved (let alone coded) that this is really a distraction and a waste of a developers time (not to mention a small decrease in overall performance by the extra layers of code).

The main issue here is again, that of team efficiency, and focusing on key risks - wrapping the logger for decoupling is such a low risk item. However a bad implementation of the wrapper is essentially a high risk item.

Again in the "buy / reuse vs. build" argument it's better to "buy / reuse".

Have you seen any funny wrapping layers? Probably the funniest I've ever seen was wrapping JDBC itself! Now I've never seen it again or otherwise it would have its own blog entry.

11/8/06

Structural anti-patterns in Code

Bad Smells you'd have to be blind to miss
(For more on synaesthesia check here :-) But I digress . . . .)

The more code reviews you do, the more you realize that in many cases you can spot issues or "bad smells" (the name popularized by Martin Fowler and coined by Kent Beck, I believe) without really reading the code. That is, you can see potential issues just through a quick visual scan - say 40 lines of code in 3 seconds - definitely without reading and understanding each individual line.

I call these "Structural Anti-patterns" because you can see them just from the simple structural outline of the code. If you replaced all the text of the file, character-by-character with Wingdings you could still probably see them . . .

Here are a couple of "obvious" ones to start with

1) Class Too Long
Well you wouldn't even have to look at the class itself - you could just tell by the size of the file.

Related . . .
Too Many instance variables
One that probably correlates a lot with "Class Too Long" is a class having too many instance variables - unless it's a big value object / data transfer object, this usually it signifies a class trying to do too much.

2) Method Too Long
If a method goes beyond 3 to 4 "pages" of scrolling you've got a good candidate for refactoring by creating helper methods etc.

3) No Unit Tests
As for (1), you don't even have to open the file to notice this - you can usually just tell from the directory structure if a class has unit tests or not.

4) Package too big
Once a package gets beyond about 12-15 classes it should become a candidate for breaking into appropriate sub-packages. You can usually partition packages by such things as function e.g. data access etc.

Now at a little more detailed level of scan . . .

5) Too much going on in a catch block
I'm not sure if this is a "classic" bad smell - but for me I'm often intrigued when I see more than 3-4 lines in a catch block - beyond logging / wrapping & rethrowing an exception or a simple method call - a person shouldn't usually try to do too much there. Perhaps there shouldn't even be a catch{} block - they should just do try{}/finally{} and leave the rest to the caller.

Often I've seen this "bad smell" when a person uses Exceptions for flow-control (eek!)

6) Missing Finally block
These days I like to stop at each try/catch block and ask "Should there be a finally{} block?". I think it's a good exercise as often I notice some resource (e.g. memory, file handle, DB connection) I should be releasing or at least be considering to release.

7) Switch statements
Typically I pause when I see these - and they really do stand-out in code - and typically I find either an instance of duplicate code (because usually switch statements don't just occur in ONE place) or I find one or more good candidates for polymorphism

8) Too many input parameters
Beyond 5-6 input parameters, a little warning signal goes up that a method might be "over-reaching" and doing too much

9) Too many Exceptions in the "throws"
Beyond 3 exceptions in the "throws" section of a method declaration I get another warning sign of methods probably doing too much

10) Too many catch blocks
Very similar to #9 when I see a try{} followed by more than 3 catch{} blocks then either the try{} block should be broken into smaller, more meaningful methods or individual methods being called are probably guilty of #9. Sometimes the exceptions being caught are so closely related that they either should be combined into one exception, or give them a common super-class which can be caught.

Summary
Code reviews don't have to be long, painful and drawn-out processes - a lot of value can be gained from just quick scans of code. Of course after these issues are addressed, more value can be had by a more thorough review (by who has time for that these days?)

Do you know of any "bad smells" that are blindingly obvious?

11/2/06

Thoughts on Agile Methods - XP and the like.

Usually when some tool, technique or methodology inspires an almost religious or fanatical following it's a "bad smell" for me that makes me approach things with a heightened sense of skepticism (probably from all those years of training to be a scientist/engineer)

Agile methods such as XP are definitely in a "camp" that inspires such a following and is probably second only to Ruby or Spring in that regard. Also recently a few blogs have had a bit of back-and-forth on Agile methods (for example this and this)

However funnily enough despite my skepticism I think Agile methods have really added quite a lot to the toolset of architects and developers.

In this blog entry I will focus on Extreme Programming (XP) as it's what I know (so some of this may or may not apply to Scrum, Crystal etc.)

The Gems
1) Unit Testing
Thank the heavens for JUnit. Unit testing is great for the obvious reason of testing your code to make sure it works like you think it should (duh!). It's also a great "artifact" that helps to make up a part of a regression test that can be run at anytime.

But most of all, like a good design document, unit testing helps you think from the outside-in (black box) of what you are creating and what the interface should be and how it should behave to the caller. It also helps capture in code small pieces of the user requirements and design that may not be expressed elsewhere. Invaluable!

(Note, however, as is discussed later a set of unit tests does not replace a good architecture/design document)

2) Frequent, Small Releases
My favorite paradigm for thinking about software projects surrounds risk, and many of the biggest risks such as user dissatisfaction, harder/longer integration, discovery of and fixing performance issues etc. are mitigated by smaller and more frequent releases. The longer you go without releasing the more chance you'll "drift" from the path to working code and user satisfaction.

The other positive outcome of this is increased team morale. There's nothing like a bunch of working releases under your belt to make your customers happy and keep you and your team positive and happy! In doing so, your customers / users become more trusting and are often willing to give you a little more slack. Conversely several missed releases is a morale and motivation killer and often introduces a lot of tension with your users/customers - exactly what you don't need!

3) Shorter ("stand-up") meetings
Now I'm not saying no to any meetings - just less of them and shorter. I've had projects where there were two 1-hour whole-dev-team meetings in the morning. Usually they ran over and by the time they were done it was practically lunch! Lunch-time and not much really achieved as a team.

Too often most of the 8-15 of us were debating minutiae that could and should have been resolved between 2-3 people.

I like quick update meetings where everyone gives a quick status - what they are working on, how its going, any surprises, anything blocking etc. It takes about 15-20 minutes. If there's something that needs resolving I make sure the relevant people meet at some point that day and during the day the project manager and I help people work on the blockers.

The best managers I have ever worked with were enablers who focused on removing roadblocks that prevented or impeded our success.

4) No overtime
There's no "backup" for your brain - once you;re toast you're done! Full-on design, development and testing is hard-going day-in day-out. Beyond the usual 40-45 hours a week, burn-out is inevitable, at least for us mere mortals :-)

5) Frequent integration
I love this for the same reason I love frequent, small release - risk reduction and increased morale.

6) Refactoring
We very rarely write our best code the first time, whether due to lack of experience, tight deadlines or the build-up of too many patches on the same old worn-out code, refactoring is a great practice. Small classes and small methods that "do one thing and do it well" are a beautiful sight to behold. There are many great refactorings out there.

Again - frequent, small refactorings combined with frequent unit testing, integration and release help keep the code working and maintainable.

7) Constant Communication (with users and with developers)
Again it's about risk reduction - unit testing is great because it helps make sure your class/method works like YOU think it should. But is that behavior really what the requirements / design dictate? Perhaps what the requirements say isn't really what the user needs (yes that happens too!). Constant communication helps mitigate that risk.

The "Duds"
1) Pair Programming
Now I've never done much pair programming so I'm not dissing it based on it's inherent merits or any real-world experience. It's just that XP tends to get "shot down" by management the second they hear about "pair programming". I think XP would get a lot more traction if they played down this aspect. I've found XP valuable in so many other respects but can't really say so to managers for this issue primarily.

2) De-emphasis of architecture and design
I think XP, in rejecting heavy-weight methods swung the pendulum too far the other way in de-emphasizing (and in many ways rejecting) technical design. Many XP big-wigs have tried to address this apparent misconception but from everything I read about XP - a traditional design is irrelevant - whether it's big or not.

Check out good articles by Martin Fowler and Scott Ambler

Frankly I think this can only really work when you have a really awesome, high-powered and very experienced team of managers and developers. Few of us are lucky enough to be in that position.

Clearly I have skin in the game - being an Architect. But I can't imagine how an "emergent" design can be nearly as good as a well thought-through and planned one. And I'd rather read a 20-page architectural spec (with lots of diagrams) than trawl through thousands of lines of unit test code.

That said, I do agree with XP that "Big Design Up Front" is risky but unless you do some serious design up front, you often don't know some of the biggest and nastiest technical risks.
However some big risks only come to light in code so a careful balance needs to be struck.

I guess the point is, I don't think you can ever truly know how much architecture/design is the right amount up front but that doesn't mean you should just throw up your hands and say "the design is emergent - OK let's start coding".

In the same way that Eisenhower said "Plans are worthless, but planning is everything" perhaps "Designs are worthless, but designing is everything". The end product of the design will ultimately change before coding is complete but in the act of designing you uncover so many things!

3) Rejecting other traditional methods when "Waterfall" is a fact of life.
Let me start by saying that by "waterfall" I mean the simple process of sequential steps: requirements --> design --> coding --> (user) testing --> installation & maintenance.

Here's my issue with rejecting waterfall - it's like rejecting Gravity - that's all well and good if you live in a parallel universe where the laws of physics don't apply :-)

There's two issues with rejecting Waterfall and traditional methods

i) It is impossible to test (completely) without working code
Unit testing is an important part of testing but *FAR FROM* the whole picture. The hardest testing phases are Integration, System-wide and user-testing (oh yeah and performance testing). The process diagrams from XP seem to indicate there is unit testing, and "acceptance" testing and nothing in between (see here also). Frankly I would *NEVER* go from unit testing to user testing without something more substantial in between.

Also as anyone who has written lots unit tests know- it's very hard to map from a user test-case to a discrete set of unit tests. You would end up writing so much code it's not really worth it - why? Because of all things user requirements are the most volatile of all! Now you've written so much extra code that must also be thrown away.

So IMHO the largest part of all testing comes *AFTER* coding and unit testing. It simply can be no other way.

ii) You cannot skip design
Whether you create a design or not - the second you write a line of code you are realizing a design - it may be in *your* head but it's still a design. If you are on a team of more than about 7-8 developers then to really "scale" communication a written and agreed upon design is a very helpful (I would say 'necessary') task on the path to to success.

Personally I've also found that from writing out a design I've found errors and holes in my own thinking. I've uncovered serious and major risks just below the "architectural" level - deep in a component design. Sometimes this risk will make or break a project! The brain's limitations on perception, rationality, logic and short-term memory are well known (at least by statisticians and scientists anyway) and also argue against the mid- to long-term viability of an "oral/aural" design/architecture.

So in essence the tasks *HAVE* to be in the following generic "Waterfall" order
requirements --> design --> code --> testing
but that's not to say there is no interplay / iterations between and across phases but at a high level that's all it is.

As I've said before Agile has taught me that at many times "less is more" - so I tend to write smaller design documents with lots more pictures and try to always keep them under 20-30 pages or so. From there on, 1-on-1 and team meetings can help get the details out. Also you can farm out individual component designs to individual developers - each creating a small 5-10 page document. Beyond that you do get the "glaze over" effect in people's eyes.

Overall
IMHO agile methods are probably most valuable not for the methodology itself but for challenging the status quo (e.g. CMM) with it's huge tomes of documentation, certification
paths and the need for so many dedicated people in "small" roles - it's no wonder consulting firms love it as they can bill for so many people!

Personally I've added several of the practices to my "toolset" especially
1) Unit Testing
2) Frequent, Small releases
3) Frequent Integration
4) Refactoring
5) Short, Stand-up meetings

But getting back to my initial point of the fervor on both sides - as with many of these things I don't see what all the fuss is about. My attitude is to take a look, stay informed, experiment with it and make a choice - take it (or pieces of it) or leave it. I've found XP to be very useful but within the context of a very "normal" waterfall model.

I look forward to hearing your collective experiences - what works for you and what does not. I'm sure I'll get some flames but I look forward to your (firestorm of) comments! :-)
Postscript
As one commentator rightly pointed out I've really only discussed XP and not other agile methods (such as Crystal and Scrum) so many of my points don't necessarily apply to them. So I guess the blog entry title is a bit inaccurate :-(
That said I'm hoping others will educate me about differences between XP and the
other agile methods. Any recommended papers/articles/links?

11/1/06

How do you handle incorrect arguments passed to a method?

What happens when your method gets passed a null object, an int that's out of bounds, a closed JDBC connection etc.?

Please vote here at BlogPoll.com

Personally I tend to throw IllegalArgumentExceptions when it's a public method (I feel weird throwing NPEs when an argument is null and shouldn't be). For private methods I tend to "let them pass" and for protected methods it depends.

But I've never been 100% comfortable with the approach as being "best". I like to hear from other developers on what they use, what they recommend, what they like and dislike?