In my previous post Implementing JEE with Spring 2.0 and BEA WebLogic I described the basic steps to use the Spring-based JSR-220 and 250 implementation within BEA’s WebLogic Tech Preview. In the conclusion of the article I stated that the use of the new framework enriches the portability of an application.
After the public availability of the source code and documentation of Pitchfork project, which is the open source project integrated into WebLogic, I decided to prove my portability statement. Therefore I take my example EJB 3.0 stateless session bean and port that to a Tomcat web container. Currently Tomcat certainly does not know anything about JSR-220 or 250 annotations.
Just to recap, here is the EJB 3.0 SLSB. You can see that I have added an @Interceptors annotation. In my opinion - and I’m not alone with that - the usecase of that annotation and the whole AOP stuff specified with the EJB 3.0 specification in general is definitely way too limited and by far too invasive (defining the pointcut right inside the advised code is not the right approach to attach an advice). Therefore please consider the use of the @Interceptors annotation as an example that I choose to demonstrate the feature set of the Pitchfork Spring add-on.
import javax.annotation.PostConstruct;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.cdupuis.ejb3.aspect.TacingAspectEjb3;
@Stateless
@Remote(Echo.class)
public class EchoBean implements Echo {
private static final Log LOG =
LogFactory.getLog(EchoBean.class);
private EchoVo echoVo;
@Interceptors( { TacingAspectEjb3.class })
public String echo(String say) {
LOG.info("echo called " + say);
return this.echoVo.getEcho() + " " + say;
}
@PostConstruct
public void init() {
LOG.info("init " + echoVo);
}
public void setEchoVo(EchoVo echoVo) {
LOG.info("setEchoVo called " + echoVo);
this.echoVo = echoVo;
}
}
and the corresponding spring-ejb-jar.xml which is still located in the META-INF directory.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="EchoBean" class="com.cdupuis.ejb3.EchoBean">
<property name="echoVo">
<bean class="com.cdupuis.ejb3.EchoVo">
<property name="echo" value="Hello" />
</bean>
</property>
</bean>
</beans>
Integrating annotated services in an web application
In order to use the EchoBean outside of BEA’s WebLogic Server, for example in an web application deployed in a Tomcat web container, and still leverage all the fancy dependency injection stuff based on JSR-220 and 250 annotations, one just need to make sure that the required bootstrapping actually happens. That can be accomplished pretty easy with the Bootstrap classes delivered with the Pitchfork framework.
A custom JeeContextLoaderListener and corresponding JeeContextLoader loads every Spring bean definition file named /META-INF/spring-ejb-jar.xml and applies Pitchfork’s JeeBeanFactoryPostProcessor to every loaded BeanFactory. Please not that the JeeContextLoaderListener is not yet part of the Pitchfork or Spring framework release.
The required code is fairly straight forward:
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.sfw.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.ContextLoader;
public class JeeContextLoader
extends ContextLoader {
private final Log LOG = LogFactory.getLog(ContextLoader.class);
protected ApplicationContext loadParentContext(
ServletContext servletContext)
throws BeansException {
if (LOG.isInfoEnabled()) {
LOG.info("Bootstrapping JEE application context");
}
ApplicationContext parentContext = new ClassPathXmlApplicationContext(
new String[] { "classpath*:/META-INF/spring-ejb-jar.xml",
"classpath:/org/sfw/jee/web/context/spring-jee-bootstrap.xml" });
return parentContext;
}
}
The spring-jee-bootstrap.xml contains just one bean definition: The org.springframework.jee.config.JeeBeanFactoryPostProcessor
Here is the required definition of the JeeContextLoaderListener in the web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<listener>
<listener-class>
org.sfw.jee.web.context.JeeContextLoaderListener
</listener-class>
</listener>
…
</web-app>
After deploying the web application the beans defined in spring-ejb-jar.xml file(s) are managed by the web application’s root Spring application context and can be used for wiring with other beans defined in servlet application contexts. Certainly all annotations are processed.
To stay with the example: The EchoBean will be advised with JSR-220 interceptor based on the @Interceptors definition, even tough the application is running on a Tomcat instance.
Conclusion
What that example demonstrated is that it is very easy to migrate a EJB 3.0 based application to any other environment without changing any application code. At the end the EJB 3.0 SLSB is certainly not a EJB anymore but a stateless Spring bean, annotated with some useless annotations (@Stateless or @Remote).That is due to the fact that the Pitchfork framework is not bound to BEA’s WebLogic Server and can be used with any other environment. Isn’t that nice … ?


Recent Activity
David Newcomb, David Newcomb, Novice, , Shaun, PrakSub, Christian Dupuis, painfulupdate, Scott, Christian Dupuis [...]
Sweepstakes, Ashley Wong, Alessandro, Reza Payami, Christian Dupuis, Senthil, Chris B, Christian Dupuis, Senthil, Christian Dupuis [...]
Paa, Daniel, electronic cigarette, suzan, Millen Store, Ralf Ebert, tek, Axel Mendoza Pupo, Christian Dupuis, Ryan Ovrevik [...]
thygu, Ralf Ebert, Haya, Tony, James, Radek, Radek, jack, nicholas, cj [...]
abc, bruno, Pat, John, joshmerry, IGC, guddu, antonio, Narada, Rakesh [...]
, Barry Smittins