Announcement Announcement Module
Collapse
No announcement yet.
Can't deploy Spring MDP due Work Manager not available for WebSphere 5.1 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't deploy Spring MDP due Work Manager not available for WebSphere 5.1

    The initial idea of turning a JMS message-driven bean (MDB) EJB into a Spring JMS Message-Driven Pojo in order to reduce the complexity and the licensing fees of the EJB container, seemed to be easy and straight-forward, but several issues have delayed my project and now I can't find a work around for an issue that is blocking me --I need your help here guys =).

    Since I can't post URLS in my first post (this is it), I am including the whole explanation in the next post.

    I am using Spring 2.5.5 and 'IBM WebSphere Application Server, 5.1.1.14' (as reported by the Administrative Console).

    I've been following ideas posted by IBM consultants Tom Alcott et al on how to use Spring JMS for deploying a Message-Driven Pojo (MDP) on WebSphere Application Server V6 through V7 here. The article clearly focuses on WebSphere versions V6 through V7; however while browsing through the Spring 2.5.5 documentation for one of the required classes, WorkManagerTaskExecutor, I found out that Juergen Hoeller suggested that "Support[ing a WorkManagerTaskExecutor] for WebSphere 5.1 ... can be built with this [WorkManagerTaskExecutor] class and its helper DelegatingWork as template".

    Since Juergen is suggesting some kind of support for WebSphere 5.1, I've been trying to use ideas from Tom et al and Juergen; however I can't seem to go ahead. Details follow.

    I followed Juergen instructions and created my own WebSphere51WorkManagerTaskExecutor (available here)and WebSphere51DelegatingWork (available here) classes, following his instructions. In order to compile this classes I had to add the 'asyncbeans.jar' jar file to my project's classpath. This is a little bit odd since I'm using WAS 5.1 and asyncbeans.jar is contained in
    Code:
    C:\Program Files\IBM\Rational\SDP\6.0\runtimes\base_v6\lib
    . While starting my server I'd see ClassDefNotFound errors during startup for the classes in asyncbeans.jar so I ended up putting a copy of asyncbeans.jar in
    Code:
    C:\Program Files\IBM\Rational\SDP\6.0\runtimes\base_v51\lib\ext
    . This would take care of the ClassDefNotFoundExceptions.

    I also created a Spring configuration file following Tom Alcott et al suggestions and everything seemed to be in place; however I hadn't configured the required Work Manager. When I started up the server I got an exception since the Work Manager was not available in the specified JNDI location.
    Code:
       <bean id="taskExecutor"
          class="org.localparty.WebSphere51WorkManagerTaskExecutor">
          <property name="workManagerName" value="wm/default" />
       </bean>
    Of course, Spring wouldn't find no Task Executor in 'wm/default', but how do I create one?

    Now, this is where I stucked up whithout knowing how to continue. To set up a Work Manager I am supposed to log into the Administration Console and navigate to Resources => Work Managers, bug there is no such category! Again, I am using 'IBM WebSphere Administration Server 5.1.1.1.1' and contradictorily enought, there are some articles about Work Managers on the documentation site for "IBM WebSphere Application Manager Enterprise V5.1.x".

    This is the Spring container configuration:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    						http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
    
    	<!-- JNDI Environment Template -->
    	<bean id="jndiTemplate"
    		class="org.springframework.jndi.JndiTemplate">
    		<!--	will enable environment when necessary, not necessary at the moment
    				since running in the same box
    		 -->
    <!--		<property name="environment">-->
    <!--			<props>-->
    <!--			<prop key="java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialContextFactory</prop>-->
    <!--			<prop key="java.naming.factory.initial">javax.naming.InitialContext/javax.naming.spi.InitialContextFactory</prop>-->
    <!--			<prop key="java.naming.provider.url">iiop://localhost</prop>-->
    <!--			</props>-->
    <!--		</property>-->
    	</bean>
    
    	<!-- JNDI Factory for the QueueConnectionFactory Resource -->
    	<bean id="queueConnectionFactoryJndiObjectFactoryBean"
    		class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiTemplate" ref="jndiTemplate" />
    		<property name="jndiName" value="CacheUpdateQCF" />
    		<property name="resourceRef" value="true"/>
    	</bean>
    
    	<!-- JMS Destination Resolver -->
    	<bean id="jmsDestinationResolver"
    		class="org.springframework.jms.support.destination.JndiDestinationResolver">
    		<property name="jndiTemplate" ref="jndiTemplate" />
    		<property name="cache" value="true" />
    	</bean>
    
    	<!-- The sound Listener -->
    	<bean id="cacheUpdateListener"
    		class="org.localparty.CacheUpdateListener">
    	</bean>
    
    	<!-- JNDI Factory for the Queue Resource -->
    	<bean id="cacheUpdateQueue"
    		class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName" value="CacheUpdateQ" />
    		<property name="resourceRef" value="true" />
    	</bean>
    	
    	<!-- JMS Transaction Manager - use when transaction management for MDP becomes necessary -->
    	<bean id="jmsTransactionManager"
    		class="org.springframework.jms.connection.JmsTransactionManager102">
    		<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
    	</bean>
    
    	<!-- Listener Container -->
    	<bean id="cacheUpdateMessageListenerContainer"
    		class="org.springframework.jms.listener.DefaultMessageListenerContainer102">
    		<property name="cacheLevel">
    			<util:constant static-field="org.springframework.jms.listener.DefaultMessageListenerContainer102.CACHE_AUTO"/>
    		</property>
    		<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
    		<property name="destination" ref="cacheUpdateQueue" />
    		<property name="messageListener" ref="cacheUpdateListener" />
    		<property name="pubSubNoLocal" value="true"/>
    		<property name="sessionTransacted"  value="true"/>
    		<property name="taskExecutor"       ref="taskExecutor"/>
    	</bean>
    	
    </beans>
    I am thinking that WebSphere 5.1 doesn't support Work Managers, mainly because the Administrative Console doesn't show a link to manage this resources If so, how can I use Juergen's ideas without actually creating a Work Manager?

    Any ideas or brainstorming on how to use a WorkManager are greatly appreciated in advance.

    By the way, before trying the Work Manager, I had a Spring MDP running; however I got annoying warnings from WebSphere during intialization and while troubleshooting theese, I ended up unconfortable about the way Spring behaves (or about the way I think Spring behaves actually). I got this warnings while initializing the bean:

    [4/11/03 11:53:41:711 PDT] 891a0 ConnectionMan W J2CA0075W: An active transaction should be present while processing method allocateMCWrapper.
    [4/11/03 11:53:41:815 PDT] 891a0 ConnectionMan W J2CA0075W: An active transaction should be present while processing method initializeForUOW.

    As a IBM troubleshooting technote explains, this warnings make sense since the Spring Listener Container creates a thread in order to iterate in the queue for retrieving any messages while J2EE specification clearly states that no threads should be created by the contained application whatsoever. The MDP works perfectly and I'm glad, however since this piece of coude might end up used by several teams in my project, I am worried on delegating an incorrect pattern or poor solution.

    The configuration of this already-working MDP is like the one provided before; but without the configuration for 'taskExecutor' and the listener container without a task executor:
    Code:
    	<!-- Listener container -->
    	<bean id="cacheUpdateMessageListenerContainer"
    		class="org.springframework.jms.listener.DefaultMessageListenerContainer102">
    		<property name="cacheLevel">
    			<util:constant static-field="org.springframework.jms.listener.DefaultMessageListenerContainer102.CACHE_AUTO"/>
    		</property>
    		<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
    		<property name="destination" ref="cacheUpdateQueue" />
    		<property name="messageListener" ref="cacheUpdateListener" />
    		<property name="pubSubNoLocal" value="true"/>
    		<property name="transactionManager" ref="jmsTransactionManager"/>
    		<property name="sessionTransacted"  value="true"/>
    	</bean>
    It seems that Spring should use worker threads provided by the application container instead of creating its own. WorkManagerTaskExecutor could accomplish so, but as I described before, how can I make the WorkManagerTaskExecutor work for WebSphere 5.1?

    Regards,

    Gerardo Costilla (localparty)
    Last edited by localparty; Dec 19th, 2008, 10:44 AM. Reason: Included already working MDP, with side note about the ackward warnings from WebSphere
Working...
X