Monday, June 30, 2008

Using custom spring annotations in the Web and App tier

I had blogged earlier about why I thought Spring 2.5 annotations were really cool and well implemented. I had mentioned in that article how one could use one's own custom annotations through Spring 2.5 to inject dependencies into web application classes as well as the EJBs in the application tier. I went ahead and tried this out for the web and app tier to see how challenging this really was. It required the web classes that had my custom annotations to be instantiated through Spring. The Struts2 framework that's really getting a lot of momentum these days (check out Matt Raible's stats on this here) integrates well with Spring and though the documentation is not thorough, the link here gives a fairly good idea of how one goes about Spring enabling struts2. The gist here is that the object factory for all struts actions is the StrutsSpringObjectFactory. The configuration of my web.xml really needed only this listener:

  <listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

I also had an applicationContext.xml (under WEB-INF) that scanned for my own custom annotations. So that allowed my Action classes to use my custom annotations. With Struts2's native annotations, you don't need to worry about the struts-config.xml for result-jsp mappings either. Its all there in your action class. I even had advice around the action to capture timing stats thus implementing "seperation of concerns" to the hilt!! Well that took care of the web tier.

My app tier was EJB 3.0 based and I found that Spring had an interceptor that helped my cause. So my session facade had to be annotated with my custom Spring interceptor as shown here:

@Stateless(name = "HelloWorldService")
@Interceptors(MySpringBeanAutowiringInterceptor.class)
public class HelloWorldService implements HelloWorld, Serializable

The custom Spring interceptor essentially helps me to use a custom annotation (my own type for autowiring) in the EJB. The code for the interceptor looks like:

public class MySpringBeanAutowiringInterceptor extends SpringBeanAutowiringInterceptor
{
@Override
protected void configureBeanPostProcessor(AutowiredAnnotationBeanPostProcessor processor, Object target) {
processor.setAutowiredAnnotationType(CustomAutowiring.class);
}
}

Now here came the tricky part - I had to create the beanRefContext.xml for Spring and had to have it load up another context file that had information to setup Spring to search for my custom annotations as so -

<bean class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg type="java.lang.String" value="ejbApplicationContext.xml"/>
</bean>

In the ejbApplicationContext.xml, I setup the component-scan tag to search for my annotations. This worked though I was initially at a loss as to why I need to specify two context files to get dependencies to be injected by Spring. I found the reason for this on the Spring forums (by Juergen Hoeller) -

Essentially, your "beanRefContext.xml" file will typically define a ClassPathXmlApplicationContext which in turns loads your actual beans. The "beanRefContext.xml" mechanism allows multiple such shared ApplicationContexts to co-exist, differentiated by bean factory locators. In the default EJB3 case, simply define one such ApplicationContext which will be picked up automatically, regardless of name.

You can also read more on this in the Spring docs here. The other thing also was that I had to make sure I had the correct set of libraries in my EAR. Those libraries were:

- spring.jar
- asm-2.2.3.jar
- asm-commons-2.2.3.jar
- aspectjrt.jar
- aspectjweaver.jar
- common-annotations.jar
- commons-logging.jar
- log4j-1.2.14.jar

Overall, I found that the web side Struts2 integration with Spring seemed much more cleaner that the EJB one. At this point I would still recommend this approach, but make sure you have a little bit of time on your hands to get this working exactly the way you want it. If you are interested, I can further share any other information - just call out.

I will continue to tweak and research on the EJB implementation - but overall, this approach still makes for an interesting application design.

Sunday, June 8, 2008

Microsoft TechEd 2008: Oslo and WCF

This was the first time that I attended a Microsoft TechEd event. While the sessions were interesting, there was a lot of emphasis on WCF ( Windows Communication Foundation ), and understandably so I guess - its essentially a platform(WCF extensions) on a platform (.NET) and I say that because of the swooping changes that are brought to the .NET platform by adding the WCF implementation to it. At the core, WCF implements WS-* standards for web services, however there are very few vendors (if any other) that have implemented WS-* to this degree and simplicity. I think that right there should be a wakeup call for Java folks. I was pretty impressed with what I saw of WCF and look forward to playing with it.

Microsoft's codename "Oslo" project could also potentially be another knee-jerker for the Java camp. "Oslo" sounds interesting as a concept and is essentially a broad set of innovations touching many aspects of the application lifecycle, including languages, development tools, integration, application management, and more. The whole concept of "Oslo" is based around models. One would jump to the conclusion that this is Microsoft's MDD (Model Driven Design) methodology. However, its not really that. "Oslo" consists of 3 parts : Repository, Lifecycle manager, and schema language. The repository maintains the various model artifacts, and so models in the case of "Oslo" are anything in IT that has a representation through the schema and is maintained in the repository (eg. things like applications, computers, processes, services,SLAs). The schema extensions help to formalize definitions of basic entities (infrastructure and business based) in a software's life-cycle. What is really cool is the lifecycle manager uses the repository and the schema extensions to manage the entities represented. So for example, if a component is deployed on a certain platform/environment, on multiple machines, lifecycle manager will know about this profile and deploy the component accordingly onto the defined platform/environment.

All this occurs through sophisticated visual integration with tools like Visual Studio, Visio and Oslo's own visual editor - as a way to provide the same information to tools that people typically use in different roles ( analyst, developer etc). So Oslo really seems to me like a tool from the software development lifecycle perspective - modeling a component/service/process, building it, and then moving it and deploying it to an environment.

The key here is that there are so many bits and pieces to this colossal, that only a company like Microsoft could pull this feat through - the Open space world will probably have a hard time replicating such an effort and collaborate effectively. That would invariably give Microsoft a competitive edge. Another scary thought for the Java folks.

From what I saw at TechEd, Microsoft has some interesting technologies that have a lot of potential. C# as a language is evolving better and more rapidly than Java and so is the declarative language F# over something like Groovy on the Java side. In a services world too, WCF's ease of use and WS-* richness also place Microsoft very well in that space. "Oslo" still is a mystery, but if it comes close to what Microsoft is talking about, I think the Java space could find itself in troubled waters very soon :(.