November 23, 2011

Lunch-N-Learn Ideas? Use Sonar Hotspots

Are you eager to get your team together for a lunch-n-learn with free pizza (and beer), but can't come up with any ideas on which to present?

Or maybe you just want to get heads down and make some high impact, quality improvements to your code base, but don't know where to start.

I've written about one idea for the latter in Risk Homing Metrics. But lately, I've been using another technique to find real, practical ideas for lunch-n-learns and quality improvements: Sonar's Hotspots.

I like Sonar because it aggregates multiple metrics into single views. It also allows you to view various levels of detail: high, overall project stuff for manager types all the way down to lines of code for developers. By using the Hotspots feature, you can quickly find the top five problem areas in various categories = real, applicable ideas.

If you've never used Sonar, take a look at the Hotspots for ActiveMQ. You can also view many of your favorite open source projects' Sonar results on Nemo.

As always with metrics, you need to weed out the false positives and tweak Sonar so that it only picks up real issues. Otherwise, you risk people getting discouraged and not using the tool.

Now, go schedule that lunch-n-learn and order some pizza.

November 22, 2010

Maven Tip: Finding Default Project Settings

Originally published 25 Nov 2009

Have you ever had to override a default project setting in Maven and didn't know the exact setting?  A google search could do the trick, but here I'll describe another way.

As an example, suppose you're converting an existing Ant build that doesn't follow the standard Maven project structure.  Maybe your project puts its source and test code right under src and test.

You start the conversion by creating a bare bones POM:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>someproject</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Then, you think: "Okay.  My project structure doesn't follow the defaults.  I'll want to change this eventually, but I want to see if this POM is okay.  I don't like to go long periods of time without seeing something working.  How do I tell Maven to change where it should look for source and test code?"

By running mvn help:effective-pom, you can find this quickly:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  ...
  <build>
    <sourceDirectory>.../someproject/src/main/java</sourceDirectory>
    <testSourceDirectory>.../someproject/src/test/java</testSourceDirectory>
  ...

"Oh yeah.  There are the settings.  All I need to do is change this in my POM"

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>someproject</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <testSourceDirectory>test</testSourceDirectory>
  </build>  
</project>

The help:effective-pom goal is a trick I use to quickly look up a project setting as well as to see all the settings together for a given project or module.

Java vs. Scala Ceremony

Originally published 17 Nov 2009

Man, every time I go to write some Java code these days, I just cringe at all the effort.

public class Person {
    private final String firstName;
    private final String lastName;
    private final int age;

    public Person(String firstName,
                  String lastName,
                  int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }
}

Sure, it didn't take me too long to write the Java code because of the handy dandy source code generation features in my IDE. But the real problem is the maintenance. I or someone on my team will have to read this cluttered code many more times than the one time I wrote it.

Take a look at the equivalent Scala code:

class Person(val firstName: String,
             val lastName: String,
             val age: Int)

Which version would you rather maintain?

97 Things Every Programmer Should Know

Originally published 8 Sep 2009

The web site for the 3rd book in the 97 Things series recently went public.  This one is targeted at programmers.  There are 88 contributions that have been edited (mine is #57) and the exact 97 entries that will go into the final book have yet to be identified.

Some of our industry's thought leaders have already made contributions.  If you'd like to contribute and possibly see your name listed alongside them, see How to Become a Contributor.

Risk Homing Metrics

Originally published 28 May 2009

Recently, I attended a talk by Neal Ford.  He was talking about a couple of metrics you can combine to identify areas for refactoring: cyclomatic complexity and afferent coupling.  He used the ckjm tool to determine what classes were both complex and used by lots of other classes.  Start refactoring these was his recommendation.

I immediately thought of Crap4j; another tool that combines a set of metrics for identifying the riskiest areas of the code base to maintain.  Crap4j implements the CRAP metric, which combines cyclomatic complexity and test coverage, but at a method level.  If a method is both complex and not very well tested, then it's risky to change.

This all led me to a new, more ultimate set of metrics that could be combined to home in on the riskiest areas of a code base:
  1. Code coverage
  2. Cyclomatic complexity
  3. Code execution frequency in the real world
Complex code, executed very often, with low test coverage.

For practical purposes, I like sticking with the granularity of a method.  I can use tools like Cobertura to find the test coverage and JavaNCSS to find the cyclomatic complexity.  (Isn't cyclomatic complexity best applied to the method level anyway?)

That just leaves me with the which-methods-execute-the-most-in-production problem.  This is hard because I can run the other two as part of a continuous build, but I won't be able to identify the hot methods until I get to production and measure true usage.  So the static and dynamic metrics will always be out of sync at some level even if I could get estimated usage through continuous functional and higher level testing.

So what can I do?  I want this to run as part of a continuous build to get feedback as soon as possible that a method is getting a little risky (or with a legacy code base, is already risky).  So, I'll fall back on afferent coupling for practicality.  But afferent coupling is typically measured at a package level.  The finest granularity that I'm aware of with current tools is measuring at a class level with ckjm.  That's a good starting point for identifying highly used code.

So here's my plan.  Use the CRAP metric to find the methods and then factor in the afferent coupling of the those methods' classes to give a prioritized list of methods to go clean up.  I'll see how this goes and consider factoring in method execution frequency from higher level testing runs.

97 Things Every Software Architect Should Know

Originally published 2 Mar 2009

I recently received my copy of 97 Things Every Software Architect Should Know.  I'm honored to be included among some great minds in the software development field.  Richard Monson-Haefel, Neal Ford, Udi Dahan, Kevlin Henney, and Gregor Hohpe are just a few of the thought leaders who made contributions.

My contribution was about starting with a Walking Skeleton and building it out.  I was lucky enough to learn this early in my career while working alongside a gentleman named Bernie Thuman.  Bernie applied this technique as he led a team developing a 3-tiered distributed enterprise application.

Anyway, I'm glad to be a part of this project.  The book is filled with pearls of wisdom and is a must read for any software architect or really any professional looking to develop better software.

Git And Continuous Integration

Originally published 13 Nov 2008

Subversion is the de facto version control system of the day, but Git is the rising star.  More and more people are using Git, but I'm a bit concerned about its effects on Continuous Integration (CI).

First some background...

Subversion follows a centralized repository model.  So does CVS and many others.  There's one server that everybody commits to.  Git can follow suit or be configured in a distributed fashion.  In a fully distributed model, each developer has a private copy of the repository.  Mercurial is an example of a distributed version control system.

My concern is really with the distributed model.  One of the appeals of this model, and particularly with having your own private repository, is the ability to experiment and check-in/commit at a much finer-grained rate than with a centralized model.  With a centralized model, you need to be more careful of your commits.  Otherwise, you could break the build and everybody else.  So consequently, you commit less frequently here.

But what's better in the context of CI?  I have to be honest and admit that I've never used the distributed model on a project, so I'm being theoretical here.  My gut feel is that with a distributed model, integration will be less frequent.  I believe people will check in to private repositories more often, but will push those changes to the main integration branch less frequently than people committing straight to the main branch in a centralized model.  In a centralized model, integration is in your face.  You can't commit without thinking about it.  In a distributed model, you can get carried away in your own little world.  And we've learned in the agile community that we should be integrating early and often, haven't we?

I compare the distributed model with multiple repositories to a centralized model with multiple branches.  If you can accept this analogy, you can probably see how integration would be less frequent.  I fear with Git that people will adopt more of a distributed model and thus, CI will suffer.  This is pure speculation on my part, and I'm interested to see how things play out.

So my point here is to be mindful of using lots of repositories with Git and its potential negative consequences on CI.

For some more comments on using Git and CI, particularly on larger teams, see this.

Essence Over Ceremony in Unit Testing

Originally published 9 Aug 2008

There's been some talk recently about essence and ceremony, particularly regarding JVM programming languages. My first remembrance of this discussion was reading this blog entry from Stu Halloway.  Java is a ceremonious language because there's a lot of extra, requried typing that blurs the essence of what you're trying to communicate in the code.

I want to talk about essence vs. ceremony in unit testing.

If I give you this:

OrderTest
    testCalculatePrice
        1 20.00
        2  5.00
          30.00

Can you tell what this is about? This is a specification of the calculatePrice() method on an Order object, where there are two LineItem objects and the expected price is $30.00. Did you figure that out without the explanation? This is essence.

Instead, what you often see is something like this:

public class OrderTest {
    @Test
    public void testCalculatePrice() {
        Order order = new Order();
        Product product1 = new Product(20.00);
        LineItem lineItem1 = new LineItem(1, product1);
        order.add(lineItem1);
        Product product2 = new Product(5.00);
        LineItem lineItem2 = new LineItem(2, product2);
        order.add(lineItem2);
        assertEquals(30.00, order.calculatePrice());
    }
}

Here, you're blinded with irrelevant details that obscure what this test is all about. The essence of the specification is buried in details. What you want is clarity at this level.

You can factor out the obscurity with something like this:

public class OrderTest {
    private Order order = new Order();

    @Test
    public void testCalculatePrice() {
        lineItem(1, 20.00);
        lineItem(2, 5.00);
        expectPrice(30.00);
    }
}

That's gets us about as close as we can in Java.

A consequence of this approach is that you have more methods overall, but I've always felt that clarity trumps in specifications. Others have agreed.

What's interesting with these helper methods is that I can change how I implement them and not change the higher level, essence methods at all. For example, in lineItem() I can inject real production objects (as I did in the original example with LineItem and Product), or I can inject a mock or stub LineItem.

So my suggestion is when you are specifying these high level methods, attempt to only show the essence of the test and factor out the ceremony.

Quotes from No Fluff Just Stuff

Originally published 28 Apr 2008

I just returned from this past weekend's No Fluff Just Stuff conference in Reston, Virginia.  As always (this was my fifth show), I had a great time conversing with my peers and the excellent speakers.

The following are some memorable quotes/paraphrases in chronological order.  Some disclaimers: 1) you should always take quotes in context and 2) I could have misinterpreted the intent of the speaker.  I'll try to provide some comments for additional context.

David Hussman: "You need to respect the pomodoro," quoting an Italian manager of a team who used a tomato timer.  They would work hard for 25 minutes, then take a 5 minute break.  When one developer wanted to keep working...

David Hussman: "Sometimes stand-up meetings turn into stand-there meetings."  This is when nobody is saying anything and we're just going through the motions.  I've definitely experienced this.

Venkat Subramaniam: In the context of Guice, when comparing annotation and xml configuration, "Both XML and annotations are evil.  Annotations are the lesser evil."  My opinion is that annotations are a good addition to the Java language, but can certainly be overused.  This may be what Venkat was talking about.

Andrew Glover: "Some people say, 'Behavior-Driven Development (BDD) is Test-Driven Development (TDD) done right', but I say BDD is Customer focused TDD."  BDD is closer to the customer's language.

Neal Ford: "If there were a book written today about real world software development, it would be called Accidental Complexity, Ceremony Over Essence, Ensuring Your Job Security written by the Enterprise Architecture Team."  Neal had tons of good quotes from his excellent keynote.

Venkat Subramaniam: "We constantly create whack-a-mole systems.  Fix the code in one place and this other, seemingly unrelated part of the code breaks."  Venkat was comparing software development with the children's game.

Brian Sam-Bodden : "Remember when you had to go outside your IDE to access your version control system?  And then, that functionality was integrated with Eclipse?  That's what Mylyn does for task management."  Less context switching keeps you focused.

Jared Richardson or Neal Ford: "Ted Neward is the Las Vegas of speakers.  You have to go see him at least once."  I always enjoy Ted's sessions.

Ted Neward: Sarcastically, "The code is perfect when it leaves my desk.  Something mystical happens afterwards that introduces bugs."

Ted Neward: "The Teddy Bear Technique has the added advantage of keeping people away, particularly when you're caught talking to it by a manager."  The Teddy Bear Technique is the act of explaining your problem to a stuffed animal, and then suddenly solving it as you start to question your assumptions.

Ted Neward: "Oh Great Debugger, tell me where the bug is."

Jared Richardson: "Take a shortcut here, another shortcut there - you get to a point where you're so busy paying interest, you don't have time to pay the principal."  This was in his talk about credit card software development (Technical Debt ).

Jared Richardson: Quoting Watts Humphrey, "Developers are caught in a victim's mentality."  We never think it's our fault, it's always somebody else's.

Expert Panel: When asked for two words about SOA, some of the phrases were, "WSDL sucks", "Consider REST ", "Overly complex"

Expert Panel: When asked for two words about closures, one of the experts said, "Use Groovy"

Mark Richards: "Java has become over-bloated and way past its usefulness as a general purpose language."  I think he was the one who said, "Use Groovy."

Jeff Brown: "If we could start [Java] from scratch today, Java would look like Groovy.  Groovy is the preferred general purpose language."

Jay Zimmerman, Symposium Director: "If you want management approval to use Groovy, don't call it Groovy, call it Next Generation Java."  Managers freak out when they hear you want to use something called 'Groovy.'

Ted Neward: "Your peer group is more important than any tool or book we can recommend."  Great advice.

David Bock: "The existence of the system changes the requirements of the system."  Dave was talking about how seeing the system run changes the customer's mind of what he really wants.

David Bock: "Never believe someone who tells you he's 90% done."  Ever notice how that last 10% takes a long time?

I look forward to next time.

Hudson CI Game Plugin

Originally published 17 Apr 2008

redsolo has implemented a version of The Continuous Integration Build Game.  It's a Hudson plugin and is described here .  Way to go redsolo!