Wednesday, February 6, 2008

On OSGi and misunderstanding

I just finished reading this: Robert Cooper On SOA, OSGi And More.

Kind of sad. OSGi is not maven (ha ha), and will not download SNAPSHOTS with each run. It is fairly obvious that Robert is missing the whole point of OSGi or he is just misinformed.
His comment "... OSGi, and why I would never allow it in “my” enterprise. In “my” enterprise I want absolute control over what every service has in its runtime environment." brought up this anecdotal situation from my prior life.

At a "Emerging Technology" brown bag with tech leads of unmentionable client some time in 2005, me and a colleague spoke about AOP upon other things. After we were done, there was a comment from one of a "Architects" in attendance that boiled down to "This enterprise will NEVER USE AOP!". I was kind enough to point out that they were using simplified version of AOP with Servlet Filters and that AOP was not dark magic but a proven technology to modularize application concepts. Oh well, what can I say - they are still running WebSphere. (Someone should get fired for buying IBM.)

So back to Robert. "... A WAR/EAR file is an artifact that can be built by development and move seamlessly from development, to QA, staging and production as a singular, atomic unit." OSGi replaces that with a jar. On top of that it provides versioning and inherent hot deploy. Just today I must have spent 2 hours on stop/build/restart cycle. In "my enterprise" I would always choose developer productivity and flexible/dynamic deployment platform over any " ... singular artifact from the developers".

OSGi right now is the best modularization platform. By just providing guarantee that no client of my code can upcast to internal implementation of lets say exported service had me at hello! And benefits don't stop there. Read the spec. It is very good in detailing the niche that OSGi is trying to fill.

Wednesday, January 16, 2008

Sun takes MySql, Oracle consumes Bea

And the winner is ... Tomcat :)

No one cares, or at least should care by now, about a vertical stack that oracle, bea and ibm still pimping. App server as we knew it is dead. Grid based computing with some form of component based architecture, be that OSGi or SCA will be the way forward.

Thursday, April 12, 2007

Spring AOP and Legacy code

I am just coming of a very interesting project where we got to build an MVC layer on top of some existing code base. This project was fun, dynamic and we ended up doing a lot of slick work using Spring 2.0.x, Web Flow 1.0.x, Maven and it was good :)

One of the major requirements for the client was an ability to run legacy code base in parallel with shiny new MVC enabled application. After examining that legacy code base, we decided to stay away from trying to modify it at all cost. It was one of: touch here, feel consequences in modules that you did not know existed type situations. Lots of static methods, statefull services and super evil singletons. But we needed a way to use those legacy objects in Spring DI. Spring 2.0 Request scope to the rescue! Wow what a huge addition and helper.

<bean id="scopedBean" class="com.some.comp.ScopedBean" scope="request">
<aop:scoped-proxy>
</aop:scoped-proxy>
</bean>

After prototyping for a while one of my colleagues ran into ClassCastException that he couldn't recreate consistently. After digging around for a little bit I found the culprit. Down in the bowels of that legacy code base, object that we had scoped at the request in the Spring configuration was cast to the implementation/subtype. Big no no. Scoped beans are CGLib proxys and can't be cast. That was a terrible feeling for about a min or two until I remembered about Spring's Advised interface.
From Advised javadoc:
Any AOP proxy obtained from Spring can be cast to this interface to allow manipulation of its AOP advice.

Sight of relief and this code followed:

public static Object unwrapProxy(Object proxy) throws Exception {
if (AopUtils.isAopProxy(proxy)) {
return ((Advised) proxy)
.getTargetSource()
.getTarget();
}
return proxy;
}


The moral of the story: Be careful when playing with new and shinny in a legacy sandbox.

Wednesday, December 13, 2006

Spring 2.0 Namespaces - Simply

I recently ended up doing some work with Spring 2.0 namespace support.
Generally we have 4 options for creating custom parsers (from most abstract to most defined):
  1. BeanDefinitionParser
  2. AbstractBeanDefinitionParser
  3. AbstractSingleBeanDefinitionParser
  4. AbstractSimpleBeanDefinitionParser
Out of all mentioned, 4th is the easiest to use. There isn't much you need to do for AbstractSimpleBeanDefinitionParser, just specify class name to configure and make sure that attributes in xml file match fields on the class (following attribute-something to attributeSomething conversion rule).
Even though option 4 is simplest to use in terms of general knowledge of Spring bean configuration internals, the convention is fairly restrictive. Most times I am itching to have xml attribute that does not match the property name on the bean that I am configuring.
The most common case is to have something like override="true" in xml vs. localPropertyOverride in bean. Other is to control two properties with a single attribute.

In such cases I found a it very useful to create a FactoryBean with the properties from XML and implement InitializingBean or some other callback mechanism to deal with all of the if/else, multi property setting in java vs. PropertyValue and xml Nodes.

This approach works good most of the time. There are obviously situations where it is best to still deal with configuration in namespace handlers manually. This would include anything that implements BeanPostProcessor/InstantiationAwareBeanPostProcessor for example. In that situation your factory would need to implement BeanPostProcessor also or its functionality will not get invoked.

If you decide to go the FactoryBean route to move configuration to java, consider any Spring dependencies that wrapped bean has. In case it does, make sure to test your namespace extension very carefully as it will be horribly simple to introduce very subtle bugs.