"; */ ?>


07
Mar 10

Think About Code Quality

code-qualityRecently one of my friends from work asked me to help him improve the process around code quality and developer productivity. So I compiled my thoughts and e-mailed to him, but then I realized that it may be very helpful for others who are involved in software industry. Are you? Then keep reading.. :)

Although tools and frameworks listed here are JVM-based language focused, the approach can be definitely reused with any other environment / language / technology. So without further ado, here it goes:

The center of the code quality monitoring can be either Continuous Integration ( e.g. Cruise Control: http://cruisecontrol.sourceforge.net/ ) or Sonar ( http://sonar.codehaus.org/ ). Sometimes both.

Continuous Integration should be setup to “Intergarte Continuously” :) which means every time something is checked in, force a build. That is the whole purpose of “Continuous Integration”, and that is why I am really against the way Cruise Control is used on some client sites [builds on demand by pressing a build button.. grrr, back to 1990-ties].

So given that “Continuous Integration” is not misused, it will be plugged in with PMD ( http://pmd.sourceforge.net/ ) / Findbugs ( http://findbugs.sourceforge.net/ ), Checkstyle ( http://checkstyle.sourceforge.net/ ) and Test Coverage ( e.g. Cobertura: http://cobertura.sourceforge.net/ ) tools that will generate reports, and reflect the only true state of the code that is checked into the repository.

Now, as to a developer corner..

RAD is nothing more than just an Eclipse with lots of bloated (mostly unused IBM plugins). But being Eclipse it is very pluginable by nature. This means that PMD / Checkstyle / Cobertura reports can be available to developers prior checking in the code. PMD / Checkstyle at compile time, Cobertura at (test) run time. If possible, try to use something like Spring Tool Suite: http://www.springsource.com/products/sts, which is also an Eclipse, but much lighter (compare to RAD), faster and smarter “pluged-in”.

As far as testing. JUnit (http://www.junit.org/) should be aimed to cover two different separate layers of testing: Component/Unit Testing and Integration Testing. Component tests should be aimed to test exclusively content of the component with all of its dependencies mocked out ( http://mockito.org/ ). Where as Integration tests should test how well components integrate together, with all the test data staged ( in case DB is used: http://www.dbunit.org/ )

As for the test coverage, 85% to 90% is a good goal to aim for. Do not sign off, until this level of coverage is reached no matter how close your dead lines are, since if you do, that will increase amount of defects ten fold, that is just a law :)

If developers work on code that is / can be deployed to an Application Server, such as Tomcat, JBoss, Geronimo ( if you’re unlucky, Websphere :) ), consider getting JRebel ( http://www.zeroturnaround.com/jrebel/ ), it’ll boost developers productivity by.. let’s just say “a lot” :)

This is how I see it, and this really works for me, and projects around me.


10
Feb 10

Multiple Around Advices Applied to the Same Join Point

Spring and AspectJ

So, what do you think will happen if you apply two around advices to the same join point? They both call “proceedingJoinPoint.proceed()” which calls their target object.

But then if the target object is the same, then it is going to be called twice.. Hmm.. not something you would want to happen especially if that target object is a service that withdraws money from your bank account..

According to the Spring documentation, you may specify the order in which these advices are applied, using Ordered interface, so in case the target object (that service that withdraws money from your account) is called twice, you have an opportunity to specify the order of who calls it first:)

To free the minds of many from unnecessary worries, I’ll show you what really happens when two around advices are applied to the same join point.

Here is this target object (transfer money service):

public class WireTransferMoneyService implements TransferMoneyService {
 
	public void transferMoney( Money money, 
			         Account sourceAccount,
			         Account targetAccount) {
 
		// Start the "Wire Transfer" manager
		// ...
 
		System.err.println( this.getClass().getSimpleName() + " is called" );
 
		sourceAccount.withdraw( money );
		targetAccount.deposit( money );	
	}
}

And here are the two around advices that are applied to this transfer service:

@Around("com.xmen.iii.aspect.SystemArchitecture.businessService()")
public Object doSomethingOnTransfer(ProceedingJoinPoint pjp) throws Throwable {
 
	System.err.println( Thread.currentThread().getStackTrace()[1].getMethodName() +
			" \t\twas called before " + pjp.getTarget().getClass().getSimpleName() );
 
	Object retVal = pjp.proceed();
 
	System.err.println( Thread.currentThread().getStackTrace()[1].getMethodName() +
			" \t\twas called after " + pjp.getTarget().getClass().getSimpleName());
 
	return retVal;
}
 
@Around("com.xmen.iii.aspect.SystemArchitecture.businessService()")
public Object doSomethingElseOnTransfer(ProceedingJoinPoint pjp) throws Throwable {
 
	System.err.println( Thread.currentThread().getStackTrace()[1].getMethodName() +
			" \twas called before " + pjp.getTarget().getClass().getSimpleName() );
 
	Object retVal = pjp.proceed();
 
	System.err.println( Thread.currentThread().getStackTrace()[1].getMethodName() +
			" \twas called after " + pjp.getTarget().getClass().getSimpleName() );
 
	return retVal;
}

Now it’s simple: let’s run it and see what happens… And that is what happens:

2010-02-10 19:52:47,542 INFO [org.springframework.test.context.TestContextManager] - <@TestExecutionListeners is not present for class [class com.xmen.iii.integration.TransferLoggingAspectTest]: using defaults.>
2010-02-10 19:52:47,667 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [com/xmen/iii/integration/TransferLoggingAspectTest-context.xml]>
2010-02-10 19:52:47,808 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/aspect-context.xml]>
2010-02-10 19:52:47,839 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/app-context.xml]>
2010-02-10 19:52:47,917 INFO [org.springframework.context.support.GenericApplicationContext] - <Refreshing org.springframework.context.support.GenericApplicationContext@1820dda: display name [org.springframework.context.support.GenericApplicationContext@1820dda]; startup date [Wed Feb 10 19:52:47 EST 2010]; root of context hierarchy>
2010-02-10 19:52:47,917 INFO [org.springframework.context.support.GenericApplicationContext] - <Bean factory for application context [org.springframework.context.support.GenericApplicationContext@1820dda]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1126b07>
2010-02-10 19:52:48,355 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1126b07: defining beans [transferMoneyService,messageSource,org.springframework.aop.config.internalAutoProxyCreator,com.xmen.iii.aspect.logging.ServiceLoggingAspect#0,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor]; root of factory hierarchy>
"
doSomethingOnTransfer                   was called before WireTransferMoneyService
doSomethingElseOnTransfer               was called before WireTransferMoneyService
WireTransferMoneyService is called
doSomethingElseOnTransfer               was called after WireTransferMoneyService
doSomethingOnTransfer                   was called after WireTransferMoneyService
"
2010-02-10 19:52:48,433 INFO [org.springframework.context.support.GenericApplicationContext] - <Closing org.springframework.context.support.GenericApplicationContext@1820dda: display name [org.springframework.context.support.GenericApplicationContext@1820dda]; startup date [Wed Feb 10 19:52:47 EST 2010]; root of context hierarchy>
2010-02-10 19:52:48,433 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1126b07: defining beans [transferMoneyService,messageSource,org.springframework.aop.config.internalAutoProxyCreator,com.xmen.iii.aspect.logging.ServiceLoggingAspect#0,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor]; root of factory hierarchy>

So, as you can see, AspectJ and Spring are modest but smart, they chain those around advices for you, which is of course niice.

Happy Advising!


10
Feb 10

Sharing My Stargate Address

I guess you have it as well, if you use Comcast as your Internet Service Provider. Apparently they have these little Stargates that allow us to travel to different.. well not planets yet ( we, as a young human race, are starting slow ), but zip codes for starters. Inter-continent near real time travel is also available. But, of course, Earth would be our scope for now. Hopefully all the wormholes are blacklisted, and every traveler is equiped with a reliable iris.

It all started as a hunch, but then was officially confirmed by the Comcast’s Freudian slip:
My Stargate Address


19
Dec 09

UnBuzz Me

unbuzz meI am so tired of this artificial and useless layer that is being created on top of our language.

I am pretty sure it is a problem in any field, but I am a technical guy, so I am talking about technical buzz words.

As I look at it, big corporations use these useless acronyms to impress and sell. Individuals use buzz words to hide their own incompetence behind them.

Several years ago, when I joined IBM, the first thing I learned was not wonders of open source commitment, or coolness of IBM research labs, but “what TLA stands for”. Because without knowing that, I could not really read any documentation, or talk to most of the people in workplace. So what does TLA stand for? Three Letter Acronym.

And while TLA on its own is not harmful, its misuse in modern tech world is huge, and it makes it uber confusing for newcomers to understand what means what.

Afer I left IBM, I went even deeper into consulting, and just could not survive without learning more, and more, and more, and more… a little bit more of TLAs. Sometimes it’s useful to understand what the client really wants, sometimes just useful to be able to “talk corporate” to people who can’t talk any other language.

So what kind of misuse of TLAs am I talking about?

Let’s take for example “URL” (Uniform Resource Locator) – is this TLA? Yes. Is it being misused? No. Why not? Because it means one thing, and one thing only. And when we say URL, we mean just that – something that specifies where an identified resource is available and the mechanism for retrieving it.

Now let’s look at “SOA” (Service Oriented Architecture) – is this TLA? Yes. Is it being misused? Absolutely! Anywhere you go, you hear about SOA. People that work by your side, they do SOA. People who hire you, they want you to know SOA. Any software product, if it is any big, will be “SOA ready”, “SOA compliant”, “SOA leader”, etc… So you wonder, what SOA really is.. Well, nothing new, nor it is any revolutionary concept. SOA is what programming was all about from the day one – bunch of services exposed for others to use. That is IT! It is not a concept at all. So we have a TLA, and all it does it just BUZZes – no meaning behind it, but lots, and lots of confusion. Bunch Of Exposed Services, so how about I’ll call it BOES, or just BS maybe?

If SOA is not enough, let’s look at another one – “BPM” (Business Process Management) – is this TLA? Yes. Is it being misused? Absolutely! When you look at any Business, it will have at least some kind of Process, right? And it is a known fact that a process needs to be Managed in order to function. By people or programmatically, but it will be managed. So what does “Business Process Management” really mean? The answer is “nothing”. So when you hear about somebody saying that “we need to apply a BPM solution here”, think about a simple “if-then-else” conditional sentence. Example can be “if the item is ordered, then ship it”. That is it! Sometimes people refer to it as “Work Flow”, instead of BPM [where ‘M’ sometimes stands for Modeling], which makes a bit more sense. But should it have this confusing “BPM” title? No! But guess what is easier to market (read “sell”): “Business Process Management” solution or a bunch of simple “if-then-else” statements?

And these are just a couple of tech buzz words examples that make no sense.

Looking beyond tech, we have empty terms/words like: Enterprise, Immersion, Leverage, Paradigm Shift, Synergy, Tipping Point, etc… All of them create this confusing and useless layer, that hurts our language, communication, clarity, and makes us live in our buzzy little clouds with no clear idea where we are and what we really know. And no, I did not mean SaaS “cloud” YABW (Yet Another Buzz Word) or even PaaS cloud, nor I meant IaaS cloud… grrrr, buzz all around.


26
Nov 09

Learn Grails by Its Plugins

Grails PluginsHow do you approach learning new technology? Google it? Buy a book? Go to training? Start using it for your work?

Well, I figured that the answer to that would depend on the technology itself. And although I bought a Grails book, and spend sometime googling and building little Grails POC projects, and actually used it for work, I still felt that something is missing, that there is that gap between me and Grails.

That is when I discovered that the best way to learn Grails, to understand its guts, is to contribute to it.

Normally, in order to get a commiter status to a mature open source project you would have to open lots of JIRAs, provide many patches, donate many ideas, etc… In case of Grails, it is actually extremely easy and fast. Here are three easy steps to see you code posted on “grails.org”:

For more logistics refer to the official grails create plugins guide. But that is really it! That is how easy it is to join Grails developer community, and grow from a Consumer to the Creator.

I got lucky and saw a live presentation by Jeff Brown at Groovy on Grails One Day Seminar in Philly. That is when I got excited, and started to work on my own plugin during the seminar’s hackathon. Two days later I had a 0.1 version of plugin commited to github, three days later released it to grails.org. Just think about it – three days from scratch, and you can become a creator of an official Grails plugin – how cool is that?

Now go and create that plugin!