Friday, June 26, 2009

AOP - Why should you care?

Here's a snippet that, as much as I hate to admit it, resembles some code that I've been known to write:

public class BusyBodyService
{
    public Object fetch() throws Exception
    {
        // trace entry
        log("Entered BusyBody");

        // start profiler
        startStopWatch();

        // check cache
        if (isCached())
        {
            return fetchFromCache();
        }

        // fetch from database - loop until connection made or bail out
        int numAttempts = 0;
        int maxRetries = 5;
        Exception t = null;
        Object retval = null;

        do
        {
            numAttempts++;

            // set isolation level
            setRepeatableRead();

            // start transaction
            startTransaction();

            try
            {
                // -------------- pure business logic starts here -------------- 
                retval = getFromDatabase();
                // -------------- pure business logic ends here -------------- 

                // commit transaction
                commit();

                // deal with various exceptions
            } catch (DatabaseDownException ex)
            {
                log("Database is down");
                // email administrator
                emailDBA("Database is down; you're working all weekend");
            } catch (NetworkDownException ex)
            {
                log("Network is down");
                // email administrator
                emailNetworkAdmin("Network is down; you're fired");
            } catch (Exception ex)
            {
                // rollback transaction
                rollback();
                System.out.println("Caught exception; retry attempt #" +
                    numAttempts);
                t = ex;
            } finally
            {
                // close database connection
                closeConnection();
            }
        } while (numAttempts <= maxRetries);

        if (retval == null)
        {
            throw t;
        }

        // save in cache
        cache(retval);

        // stop profiler
        stopStopWatch();

        // trace exit
        log("Exit BusyBody");

        return retval;
    }
}
Although I knew better, I didn't have the tools to factor out all the orthogonal concerns:
  1. tracing
  2. profiling
  3. caching
  4. retry strategy
  5. transaction isolation levels
  6. transactional wrapping
  7. dealing with specialized exceptions
  8. cleaning up connections and other resources
All of these things can be regarded as "aspects" - cross-cutting concerns that ideally are managed somewhere besides your business logic, even more ideally in a reusable manner such that e.g.  NetworkDownExceptions are always handled the same way, and the response can be managed with single point of change; or transaction isolation levels can be managed from a central place; and etcetera. Factoring out these aspects buys you a maintainable codebase and central management of orthogonal concerns - and this will save long-term costs. Your manager should care deeply about this - since it has been said that maintenance is 80% of the overall software lifecycle cost. And since it will facilitate getting the busy code snippet above to look more like this:
public class CleanAndElegantService
{
    public Object fetch() throws Exception
    {
        return getFromDatabase();
    }
}

...I'm thinking you might care about this also (I'm assuming there's no need to elaborate on this - the difference should speak for itself). In subsequent posts I'll explore Spring 3.x AOP to see if we can't factor out all the aspects and move from busy-body to clean-and-elegant.

Thursday, June 25, 2009

Getting Started with Spring 3.0 AOP

Choosing the latest-and-greatest of various technologies may serve you well, and it may also give you some headaches. For projects with longer timelines, it's useful to deploy your first GA with up-to-date infrastructure; but in spinning things up, you're subject to early-adopter pain. Here's my recent experience with Spring 3.0.0, in particular the AOP component of that framework, shortly after that version's first release. I'll assume you've already downloaded the 3.0.0 distribution and are motivated to test-drive Spring IoC and AOP functionality.

My prototyping began of course with basic Spring Core. Since, at the time of this writing, the Spring 3.x stuff is not in Spring's repository, I couldn't simply declare the org.springframework.core jar in an Ivy file and let Ivy do the dependency resolving for me; this is the first point of pain we're bumping into (and I'm sure there'll be more). Here's how I addressed this.

A very simple program that leverages Spring IoC required these jars (which I discovered attempting to run the program and simply observing what classes needed loading, and making some decent guesses as to what Spring distro jars would provide them) :

org.springframework.asm-3.0.0.M3
org.springframework.beans-3.0.0.M3
org.springframework.context-3.0.0.M3
org.springframework.core-3.0.0.M3
org.springframework.expression-3.0.0.M3

Testing my IoC program revealed additional non-Spring class-defs-not found, and long story short I added these:

antlr-3.0.1
commons-logging

With these in place, my IoC prototype ran just fine. Other dependencies may be called for if a more sophisticated program is used; but my intent here is not to itemize the exhaustive possibilities, rather it is to document how I went about figuring things out for your (and my) future reference.

From here, I wanted to do some proof-of-concept with the AOP stuff. From my read of the Spring developer guide, I concluded I want to use Spring AOP (vs. AspectJ), and I want to use the @AspectJ annotation-style approach. I won't go into my rationale here; that's a different topic. As our project unfolds, I'll provide more insights in future posts.

To use the AspectJ annotation-style, I began by placing the following into my Spring XML configuration file:

In the beans tag, add this attibute to declare the aop namespace:

xmlns:aop="http://www.springframework.org/schema/aop"

...and at the end of the beans tag body, add this declaration:

<aop:aspectj-autoproxy/>

Now, I run my program again; note that I've added no advise or pointcuts yet - I only want to get off the ground in establishing my dependencies, of which I'm sure some are now missing. Sure enough:
ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor
Now, this one is obviously not a Spring Framework class; it's a third-party. I could probably use any repository to retrieve it, but I choose to use Spring's repository just to stay consistent. That repo is located at http://www.springsource.com/repository/app/. Interestingly enough, note that the trailing slash is a required part of this URL - my guess is that this is a RESTfully-constructed website in which the trailing slash indicates a collection, and without which the URL is not a valid identifier. But REST is, again, a different topic.

Searching for the missing class in Spring's repo, it offers me an Ivy entry, which I add to my ivy.xml and run the ivy:retrieve ant target. Here I'm assuming you have familiarity with Ant and Ivy, and know how to configure a simple Ivy environment; to digress on these topics here would make this post much too long, but I want to circle back eventually with a post on Ivy.

Running the Ivy retrieve task fetches the AOP Alliance library for me, and upon adding that to my project build, there is one more missing reference to an AspectJ class; I fetch this one using the same technique as above, choosing the 1.6.5. RELEASE version of AspectJ-Weaver. I rebuild with this in place, and re-run my program - this time, without any problems.

At this point, my goal is accomplished; I only wanted to get "off the ground" with Spring AOP. Now it's time to dig a little deeper and see what the AOP stuff has to offer.

Wednesday, June 10, 2009

Dependency Injection: Why Should You Care?

What we want in software development is maximum flexibility accomplished with minimal impact. One mechanism that facilitates this goal is dependency injection (DI), and I've come across a well-written rationale for DI - in Sang Shin's Java Passion coursework on the topic. I appreciate an analysis that takes me from square one in a step-wise fashion, so I'd like to consolidate Mr. Shin's 57-page PDF into a few bullet points here:
  1. Start with a hardwired "hello world" message in a program: not so flexible; you must recompile to change the message.
  2. Use a command line argument to allow the client of your program to specify the message: a bit more flexibility, but the program is coupled to the source of the message (command line input); you need a recompile to alter this. As well, the output format/destination/etc are still hardwired in the program. So, we see two separate concerns: a messenger and a renderer.
  3. Support separation of concerns by providing separate messenger and renderer classes: here, the program supplies a particular instance of messenger to a particular instance of renderer - so these combinations are hardwired. If you have N different messenger types with M different renderer types, you'll have an N * M matrix of API signatures - i.e. the renderer might have a setMessenger(MessengerImpl) call - and the program would have to choose at compile-time from among the N * M possibilities. This is not flexible at all, and certainly not maintainable.
  4. Use interfaces instead of implementations: the program specifies which messenger is supplied to which renderer, but the renderer setter uses a messenger interface instead of a hardwired implementation. Now logic in each can change without affecting the other, but the program is still hardwired to which combination of messenger and renderer is used.
  5. Use a factory to decouple the program from the combination of messenger and renderer: but this requires writing the factory, and the factory itself is still coupled to the combination choice.
  6. Use an external configuration file to decouple the factory from the choices: but, the factory still needs to be written, and the program is still explicitly aware of the source of the information (the factory).
  7. Use an off-the-shelf generic factory: Spring's DefaultListableBeanFactory is a better abstraction, more robust, and you're not reinventing a wheel, but the program is still explicitly aware of the need to wire the pieces together (i.e. it must supply a messenger to a renderer), and you still need to write a facade factory using Spring's generic factory.
  8. Use dependency injection, e.g. Spring: now there's no need to manually supply the dependency; the wiring is done by Spring. The program, messenger and renderer are all unaware of Spring, and these classes are testable without the need for Spring.
  9. Finally, use Spring DI with a constructor argument - now you can configure the message externally. Somewhat analogous to #2, in the sense of externalizing the message content, but in this case the messenger does not know where the message comes from.

Monday, June 8, 2009

Netbeans 6.7 + JBoss 5.1 Library Dependencies

Moving my IDE from NetBeans 6.1 to 6.7.1 (not a GA, but the nightly build 200906051401) resulted in failure in my web application compilation. I had pointed NetBeans to the same JBoss 5.1 installation as I used in NB 6.1, and associated my web app project with that server, so this "should" have worked, but did not. I don't have the time to analyze exactly why, so I won't discuss that; instead, I'll just provide the solution:
  1. Create a NetBeans library (named e.g. JBoss-5.1-Common) that points to all jarfiles under $JBOSS_HOME/common/lib, and add that to your project. Make sure to uncheck the Package checkbox for that library or it'll be added to your deployed warfile, which could result in classloading problems
  2. Add the JSF 1.2 library that comes out of the box with NetBeans - again, uncheck the Package option for the same reason.
This should address compile-time issues, or more accurately I should say "it worked for me".


Thursday, June 4, 2009

JSTL Namespaces

Along the lines of "how many times has this happened to me", once again I stumbled into the JSTL 1.0 vs 1.1 namespace confusion. So I write it down for my own future reference and perhaps your benefit -->

For JSTL 1.1/1.2, use xmlns:c="http://java.sun.com/jsp/jstl/core".

If you use xmlns:c="http://java.sun.com/jstl/core", you'll be limited to the 1.0 tags. Among other things, this taglib lacks the forTokens tag...and I'm sure more things than that.

Conveniences for equals, hashCode and compareTo

The Apache commons-lang library provides some nice conveniences to help with overriding equals, hashCode and compareTo. Here are some idioms you might use:

public boolean equals(Object obj)
{
    if (this == obj) {
        return true;
    }
    if (obj == null || this.getClass() != obj.getClass()) {
        return false;
    }
    MyObject other = (MyObject)obj;
    return new EqualsBuilder().append(this.id, other.id).isEquals();
}

public int hashCode()
{
    return new HashCodeBuilder(3, 13)
        .append(this.id).toHashCode(); // pick any two prime numbers
}

public int compareTo(Object obj) // assumes this class "implements Comparable"
{
    MyObject other = (MyObject)obj;
    return new CompareToBuilder().append(this.id, other.id).toComparison();
}

Just like StringBuffer, you can "append" as many fields as needed, in order to establish your object's identity (uses the builder design pattern). In my examples, I'm considering only my object's "natural identity", but you can likewise writeup other equality comparisons that consider multiple fields in your class:

return new EqualsBuilder()
    .append(this.name, other.name)
    .append(this.birthday, other.birthday)
    .append(this.city, other.city) // and etcetera, as needed
    .isEquals();

This facilitates not only overriding equals(Object), but writing up additional equality methods supporting various contracts. For in-depth details around the Commons Lang classes, visit Andrew Glover's writeup.