Phew that was a long title…

I recently visited a client to fix an issue with their one of their applications and fortunately after a couple of hours, this was already done. We had originally scheduled 2 days on-site and the client asked me if I wanted to use the time I had left to do some architectural analysis of their application. Clients frequently ask us to do something like this, because they appreciate good design. It’s definitely not only the coders that actually appreciate good design, but definitely also a lot of managers nowadays. This time I was specifically asked to review the maintainability of the design. They had pieces of code coming in from various locations all over the world and wanted to ensure that the original design (even with the continuous stream of new code) was kept in place. We at Interface21 use something called design level assertions (DLAs) to do exactly this.
Design Level What??
I usually just start working my way through the codebase (as the code ultimately reflects the design best–if the client is happy with the codebase that is
). I do this together with some developers hinting at changes here and there, asking questions about the rationale behind certain decisions and I always jot down a few notes. Later on I use AspectJ to capture the design in some rules. These rules are what we call design level assertions.
The tell you things about the design and can be used alongside the actual codebase to see if the original design rules still hold for the codebase. Let’s start with a short example: one of the specific things the client wanted to check was the usage of dependency lookups in the application. I quickly wrote myself a DLA for this to check if they used dependency injection in all of their application. This would be their first DLA and using this, they could quickly see if any newcomers to the project would mess up the codebase.
pointcut inMyApp(): within(com.mycompany.myapp..*);pointcut dependencyLookup() : call(* org.springframework.beans.factory.BeanFactory+.*(..)) && inMyApp();
Read this as follows: a dependency lookup is a call to any method on a bean factory from my application. The next thing to do is to declare a warning because we want pick this up during compilation and inside our Eclipse IDE.
declare warning dependencyLookup() : "Maybe you shouldn't use dependency lookups but DI";
Design level assertions can be captured in several ways. Using a tool like Checkstyle might also do the trick. I prefer AspectJ to create DLAs, as those design-level assertions actually have more of a code feel, rather than a document feel to them. When your design level assertions are part of your codebase, just as your test suite, it’s much more easy (errr, easier) to maintain them and keep them in synch with the changes that might occur to the design. Unfortunately the AspectJ development tools don’t yet fully support refactorings, so there still is some manual work in that area, but it certainly isn’t a Word document. Second of all, you can actually check the design level assertions during compilation instead of having to add an extra build step. Last but not least, you’ll actually be able to use the DLAs written using AspectJ inside your Eclipse environment. This means you’ll have nice error and warning messages inside your Eclipse IDE that reflect failed (design level) assertions. Nope, no eye candy for now, I don’t have time to take screenshots of Eclipse right now :).

The result of this DLA
After I created the DLA that checks for dependency lookups, I ran it across the client’s codebase. As the codebase was rather large, I used the iajc[i] Ant task instead of the AJDT integration that give you these oh-so nice error messages inside Eclipse.
To my surprise, they had more than 200 dependency lookups in their codebase (that was about 2500 classes big). Something must have gone wrong with the DLA I thought. I reviewed the warnings I got and they were all correct. There were dependency lookups all over the place!!
After investigating a bit more, I came to the conclusion that they had used dependency lookups to retrieve a prototype bean from the bean factory. They simply couldn’t do with a singleton, because the object (or rather, objects) they had to lookup maintained state across multiple method calls (in other words, weren’t thread-safe). I thought about a possible solution, so that we could still use the DLAs, but without seeing all those dependency lookups, all of which were actually justified.
Introducing a service locator
The final solution I opted for using a dedicated service locator would remove all the direct dependency lookups and move them all into one single place.
public class ProcessFactory implements BeanFactoryAware {private BeanFactory beanFactory; // setter omitted
public Process createProcess(String processId) {
return this.beanFactory.getBean(processId);
}
}
Instead of issuing calls to BeanFactory.getBean() directly inside the code in the application, I replaced all those calls with calls to the ProcessFactory (after having injected the ProcessFactory of course). This way, the application could still create process of all kinds of types (declared in the application context) and yet still adhere to the rules set out earlier.
Modifying our DLA
There is still one tiny issue though. We’ve removed all kinds of dependency lookups from our application, but we’ve also introduced one (the one in the ProcessCreator). So we need to slightly modify our DLA to exclude this one lookup:
pointcut inProcessCreator within(com.mycompany.myapp.mypackage.ProcessCreator);pointcut inMyApp(): within(com.mycompany.myapp..*);
pointcut dependencyLookup() :
call(* org.springframework.beans.factory.BeanFactory+.*(..)) &&
inMyApp() && !inProcessCreator();
As you can see, we only need to slight modify our DLA to reflect the changes we’ve made.
I quickly ran the DLA across the codebase again, and I only got a few warnings this time. I quickly refactored those and comitted the code the version control system.
Conclusion
As you can see, there certainly is such a thing as design for maintenance. Using DLAs and a dedicated service locator, we were able to decouple our application from the Spring APIs completely and create a less fragile and more sustainable design. Next to spreading your code across packages, that often correspond to modules or layers in your system, other things like adding annotations to certain classes (or in environment in which you’re not able to use Java 1.5 yet, a marker interface) might also help to better embed the rules of the game in the codebase; especially if you’re using DLAs with AspectJ for example.

And what about the ServiceLocatorFactoryBean??
Ah, yes, I mentioned this in the title as well, didn’t I? Well, there’s a nice alternative to having to code your own service locator, as I did in the piece above. This is called the ServiceLocatorFactoryBean and it prevents you from having to do the lookup yourself. The first thing we do is throwing away the ProcessCreator class and replace it with a ProcessCreator interface:
public interface ProcessCreator {Process createProcess(String processId);
}
This is what we’ll still be using in the component that need to get a hold of a process (so, in other words, in about 200 places in our client’s codebase). We do however still need to provide an implementation. This is what we’ll do using the ServiceLocatorFactoryBean:
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"> value="com.mycompany.myapp.mypackage.ProcessCreator"/>
This is what we will inject, instead of the concrete ProcessCreator class we’ve used in the previous example.
p.s. If you’re still not sure (and I wouldn’t be surprised) what DLAs actually are and how you can implement them using AspectJ, please leave a comment below and I might write some more about it. [shameless-plug]Of course you can also take a Core AOP[ii] course
[/shameless-plug]
[i] The Eclipse iajc task
[ii] Core AOP - Simplifying Enterprise Application Development with AOP
Hey Alef,
One question: why did you create a ServiceLocators for getting prototype beans, instead of using Spring’s lookup-method to get the prototype? I though ServiceLocators were a thing of the nineties ;-).
Great post, just the right length for the subject matter, nice examples. By the way, sorry I missed the Java Meetup on my September visit to Amsterdam (by just a few days), maybe next time!
Hello,
I’ve tried to use a DLA to ensure my persistence layer is only accessed via it’s API. My packaging convention is to have the DAO interfaces declared in myapp.persistence pacage, and any concrete implementation in myapp.persistence.* (myapp.persistence.hibernate, myapp.persistence.jdbc …)
I’m using this AspectJ DLA :
pointcut inPersistenceLayer()
: within(com.capgemini.quickstart.persistence..*);
pointcut callPersistenceImplementation()
: call(* com.capgemini.quickstart.persistence.*..*.*(..))
|| call(com.capgemini.quickstart.persistence.*..*.new(..));
declare error
: SystemArchitecture.callPersistenceImplementation() && ! SystemArchitecture.inPersistenceLayer()
: "Do not invoke persistence layer implementation";
This works (or seems to). Maybe there is a cleaner way ?
[...] in Spring.NET is to provide a ServiceLocatorFactoryObject, described by my colleague Alef Arendsen here. This allows you to write your own simple service locator interface, for example. public interface [...]