PDA

View Full Version : Refactoring MDB to use Spring



rstearns01
Nov 16th, 2004, 05:28 PM
Trying to refactor my app and implement Spring context in MDBs as described in Javadocs, Reference, http://forum.springframework.org/showthread.php?t=10705 and http://forum.springframework.org/showthread.php?t=11185, and getting the following error. Can someone please tell me what I've missed? Eventually I want to use the same xml file in web tier for common objects. I've obviously mis-used something, but I don't understand what.

Thanks.


[11/16/04 15:23:07:097 EST] 3b91743f ExceptionUtil E CNTR0019E: Non-application exception occurred while processing method "onMessage". Exception data: com.ibm.ejs.container.CreateFailureException: ; nested exception is:
java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException: org.springframework.beans.FatalBeanException: Unable to find definition for specified definition. Group:beanRefContext.xml, contextId:ejbContext
at org.springframework.beans.factory.access.Singleton BeanFactoryLocator.useBeanFactory(SingletonBeanFac toryLocator.java:374)
at org.springframework.ejb.support.AbstractEnterprise Bean.loadBeanFactory(AbstractEnterpriseBean.java:1 15)
at org.springframework.ejb.support.AbstractMessageDri venBean.ejbCreate(AbstractMessageDrivenBean.java:7 6)
at java.lang.reflect.Method.invoke(Native Method)
at com.ibm.ejs.container.MessageDrivenBeanO.<init>(MessageDrivenBeanO.java:129)
at com.ibm.ejs.container.CMMessageDrivenBeanO.<init>(CMMessageDrivenBeanO.java:66)
at com.ibm.ejs.container.CMMessageDrivenBeanOFactory. create(CMMessageDrivenBeanOFactory.java:39)
at com.ibm.ejs.container.EJSHome.createBeanO(EJSHome. java:602)
at com.ibm.ejs.container.EJSHome.createBeanO(EJSHome. java:689)
at com.ibm.ejs.container.activator.UncachedActivation Strategy.atActivate(UncachedActivationStrategy.jav a:78)
at com.ibm.ejs.container.activator.Activator.activate Bean(Activator.java:516)
at com.ibm.ejs.container.EJSContainer.preInvoke_inter nal(EJSContainer.java:2704)
at com.ibm.ejs.container.EJSContainer.preInvoke(EJSCo ntainer.java:2432)
at com.ibm.ejs.container.MDBWrapper.onMessage(MDBWrap per.java:87)
at com.ibm.ejs.container.MDBWrapper.onMessage(MDBWrap per.java:127)
at com.ibm.ejs.jms.listener.ServerSession.run(ServerS ession.java:372)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.j ava(Compiled Code))

beanRefFactory.xml in root of ear

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="ejbContext" lazy-init="true"
class="org.springframework.context.support.ClassPathXmlAp plicationContext">
<constructor-arg>
<value>ejbContext.xml</value>
</constructor-arg>
</bean>

</beans>

ejbContext.xml, also in root of ear

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!-- ========================= GENERAL DEFINITIONS ========================= -->

<bean id="log4jConfigurer" class="com.myapp.util.BasicLog4jConfigurer"/>

<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
<bean name="eventNotificationProcessor" class="com.myapp.ejb.notification.EventNotificationProces sor">
<property name="orderRequestorMgr">
<ref local="orderRequestorMgr"/>
</property>
</bean>

<bean name="orderRequestorMgr" class="com.myapp.OrderRequestorManager"/>
</beans>

Finally, my MDB:

public class OrderRetrieverMDB
extends AbstractJmsMessageDrivenBean
{
private static final Logger logger =
Logger.getLogger(OrderRetrieverMDB.class);

private OrderRequestorManager orderRequestorMgr;


/**
* onMessage handles the incoming message and the request.
*
* @param message - the incoming XML message
*/
public void onMessage(Message message)
{
logger.debug("onMessage called in Order Retriever MDB");
try
{
String responseXml = ((TextMessage) message).getText();
String correlationID = message.getJMSCorrelationID();
processMessage(responseXml, correlationID);
}
catch (JMSException jmse)
{
logger.error(jmse.getMessage(), jmse);
}
catch (RuntimeApplicationException rtae)
{
logger.error(rtae.getMessage(), rtae);
}
}

private void processMessage(String responseXml, String correlationID)
throws JMSException, RuntimeApplicationException
{

orderRequestorMgr.processEventMsg(correlationID, responseXml);

}
}

/**
* setMessageDrivenContext
*/
public void setMessageDrivenContext(javax.ejb.MessageDrivenCon text ctx)
{
super.setMessageDrivenContext(ctx);
BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance();
// bfl.useBeanFactory("ejbContext"); ** Tried with and w/o this
setBeanFactoryLocator(bfl);
setBeanFactoryLocatorKey(MassConstants.PRIMARY_CON TEXT_ID);
}

protected void onEjbCreate()
{
logger.debug("Getting manager");
orderRequestorMgr = (OrderRequestorManager)
getBeanFactory().getBean("orderRequestorMgr");
}
}

Alef Arendsen
Nov 17th, 2004, 01:32 PM
The error message has slight improved in 1.1.2 (have you tried the latest release already), it doesn't read 'definition for specified definition' anymore, but says 'resource for specified definition' instead.

You're saying you have the beanRefFactory.xml placed in the root of your ear. IIRC the beanRefFactory should be on the classpath, and AFAIK, the root of the ear isn't placed on the classpath. Could you try to add the beanRefFactory.xml to one of your jars (in the root).

Alef

p.s. I'm no expert on BeanFactoryLocators, so no guarantees :)

rstearns01
Nov 18th, 2004, 03:59 PM
Alef,
Thanks for the tip! Looks like it sees the files now. I had put a ./ in the classpath, which has worked for other resources; just not this time.
Now it's time to make it a parent to the webApp context. :)