Archive for June, 2008

Spring London User Group

Wednesday, June 18th, 2008

As you all know, Aleksa and I presented a case study at the first Spring London User Group meeting (I think we should call it SLUG); we now give you video of our presentation.
Jan and Aleksa presenting

Declarative caching and Hibernate

Wednesday, June 18th, 2008

We successfully use the Caching SpringModule. In short, this allows us to declaratively cache values returned from method calls. The Caching module supports many different cache implementations; we have picked OsCache for development. To get started, let’s take a look at the MemberService and its implementation.

public interface MemberService {
        @Nullable
	Member complicatedLookup(@NotNull ComplexArgument argument);
}

public class DefaultMemberService implements MemberService {
        @Nullable
        @Cacheable(modelId = "Member")
        public Member complicatedLookup(@NotNull ComplexArgument argument) {
                // some complex stuff
        }
}


This code works perfectly well: when you call the DefaultMemberService.complicatedLookup(...) method more than once with the same (read equal(Object)) ComplexArgument object, the caching framework intercepts the call in and only the first call will go to do the // some complex stuff.
The problem is when you return an object from a Hibernate DAO call and that object is enhanced by CGLIB. Now the cache has a reference to an object that references an invalid Session.
We found this when our integration tests worked fine on their own, but started failing when we ran them as part of our automatic build. The prospect of going through every possible code path to find out if there is a cached CGLIB-enhanced object was daunting. Luckily, Spring AOP was quick to rescue. We wrote a simple little aspect that checks that any method with the @Cacheable annotation does not return a CGLIB-enahanced object.

@Aspect
public class CacheManagerAspect {

    @AfterReturning(pointcut =
            "@annotation(org.springmodules.cache.annotations.Cacheable)",
                returning = "ret",
                argNames = "jp, ret")
    public void indicateLazilyLoaded(JoinPoint jp, Object ret) throws Exception {
        checkNotCGLIBEnhanced(jp, ret);
    }

    private void checkNotCGLIBEnhanced(JoinPoint jp, Object o)
        throws IllegalAccessException, InvocationTargetException {
        if (o == null) return;
        String name = o.getClass().getName();
        if (!name.startsWith("uk.co.package")) return;
        if (name.contains("$$Enhancer"))
                 throw new RuntimeException(
                        "You cannot cache a CGLIB-Enhanced object at " + jp);

        PropertyDescriptor[] descriptors =
                 BeanUtils.getPropertyDescriptors(o.getClass());
        for (PropertyDescriptor descriptor : descriptors) {
            Object value = descriptor.getReadMethod().invoke(o);
            checkNotCGLIBEnhanced(jp, value);
        }
    }

}


Simple, but powerful stuff from SpringModules and Spring AOP!

A Week of Web Releases

Thursday, June 5th, 2008

It’s been an exciting week on the web front with jQuery 1.2.6 and Ruby on Rails 2.1 being released, both providing feature enhancements and performance improvements.

Here is a brief run down:

jQuery

  • Event Handling is 103% Faster
  • CSS Selectors are 13% faster
  • .offset() is 21% faster
  • .css() is 25% faster
  • Exposed Speeds
  • .toggle() can now accept more functions
  • You can now unbind bound .toggle() and .one() functions
  • .index() supports jQuery collections
  • jQuery.makeArray can convert ANYTHING to an array.
  • beforeSend can cancel Ajax calls
  • Exposed Speeds

Ruby on Rails
Major New Features:

  • Time zones
  • Dirty tracking
  • Gem Dependencies
  • Named scope
  • UTC-based migrations
  • Better caching

Ryan Bates has produced some awesome screencasts on the above new features in rails. I highly recommend you check his Railscasts out.

SpringOne - Jan presenting

Monday, June 2nd, 2008

Following on from the very successful presentation given by Jan and Aleksa at the inaugural Spring User Group (SUG) meeting on Friday, Jan will be presenting a slightly extended version of the same presentation at SpringOne.

SpringOne is being held at MetroPolis Business Center, MetroPolis Antwerp, Groenendaallaan 394 2030, Antwerp, Belgium. More information can be found here.

Jan will be presenting on Thursday 12th June at 14.00 - 15.00 and both he and I will be at the Conference for most of the two days. If you are attending the conference please let me know and we can arrange to meet up over a coffee/beer.

Area51

Monday, June 2nd, 2008

We’ve now ordered a new sub-domain area51.devcake.co.uk. As you can guess from its name, we will publish all experimental code there. In fact, this will give you a read-only access to a subset of our subversion repository. You will be able to download any code that we are thinking about donating to the community, but is not yet up to scratch. The code will work, but it may not be completely documented and it may not have complete unit and integration test coverage.
The first project to appear in area 51 will be the Workflow SpringModule, which we first introduced on Friday at the Spring User Group meeting in London.