How to use JBossTS (Narayana) with Spring Data JPA - spring-data-jpa

I am investigating the use of a JTA transaction manager with Spring Data JPA. I have successfully configured Atomikos and Bitronix and am trying to configure JBossTS (Arjuna/Narayana).
I followed the instructions for configuring JBossTS for Spring and came up with the following configuration:
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true"</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.id.new_generator_mappings">false</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform</prop>
<prop key="hibernate.use_sql_comments">true</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect"/>
<property name="generateDdl" value="true"/>
<property name="showSql" value="true"/>
</bean>
</property>
<property name="jtaDataSource">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="connectionProperties">
<props>
<prop key="dynamicClass">com.arjuna.ats.internal.jdbc.drivers.PropertyFileDynamicClass</prop>
<prop key="password"></prop>
<prop key="user">sa</prop>
</props>
</property>
<property name="driverClassName" value="com.arjuna.ats.jdbc.TransactionalDriver"/>
<property name="url" value="jdbc:arjuna:database.properties"/>
</bean>
</property>
<property name="packagesToScan" value="org.example.domain"/>
</bean>
<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManager">
<property name="transactionManager">
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"/>
</property>
<property name="userTransaction">
<bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction"/>
</property>
</bean>
<transaction:annotation-driven/>
However, attempting to run the application throws the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
Caused by: java.sql.SQLException: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at com.arjuna.ats.internal.jdbc.IndirectRecoverableConnection.createDataSource(IndirectRecoverableConnection.java:361)
at com.arjuna.ats.internal.jdbc.IndirectRecoverableConnection.<init>(IndirectRecoverableConnection.java:109)
at com.arjuna.ats.internal.jdbc.ConnectionImple.<init>(ConnectionImple.java:107)
at com.arjuna.ats.internal.jdbc.ConnectionManager.create(ConnectionManager.java:110)
at com.arjuna.ats.jdbc.TransactionalDriver.connect(TransactionalDriver.java:87)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:208)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:153)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:144)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:196)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:159)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180)
at org.hibernate.resource.transaction.backend.jta.internal.DdlTransactionIsolatorJtaImpl.prepare(DdlTransactionIsolatorJtaImpl.java:49)
... 60 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.arjuna.ats.internal.jdbc.IndirectRecoverableConnection.createDataSource(IndirectRecoverableConnection.java:346)
There does not seem to be any documentation on whether JNDI is mandatory to run JBossTS and if yes, how it can be configured in a standalone application that does not use a JavaEE container.
A sample application is available on Github in case the full configuration and source code is required. The problem can be seen by running Maven tests as mvn test -D"spring.profiles.active=jbossts".

Replace the <prop key="dynamicClass"> with <prop key="DYNAMIC_CLASS">
Specify the properties file with target/classes
Use the H2 file database instead of the memory
For more information you can see narayana.io

Related

Password Encryption in Hikaricp

I am using HikariCP in a spring project.
Right now, I defined a connection like this
<bean id="hikariConfigLegacyReasonCode" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="HikariCPReasonCodePool" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"/>
<property name="registerMbeans" value="true"/>
<property name="maximumPoolSize" value="15"/>
<property name="idleTimeout" value="60000"/>
<property name="connectionTimeout" value="5000" ></property>
<property name="dataSourceProperties">
<props>
<prop key="url">jdbc:mysql://${LegacyReasonCodeIp}</prop>
<prop key="user">${LegacyReasonCodeUsername}</prop>
<prop key="password">${LegacyReasonCodePassword}</prop>
<prop key="cachePrepStmts" >true</prop>
<prop key="prepStmtCacheSize" >250</prop>
<prop key="prepStmtCacheSqlLimit" >2048</prop>
<prop key="useServerPrepStmts" >true</prop>
</props>
</property>
Here, Server name , username and password will be loaded from a property file. Is there any way to store the DB password in the property file in encrypted manner ?
Try the jasypt project. It includes a number of integrations for Spring, including implementations of:
PropertyPlaceholderConfigurer
PropertyOverrideConfigurer
PreferencesPlaceholderConfigurer
http://www.jasypt.org/spring31.html

Spring Batch : Field or property 'stepExecutionContext' cannot be found

I have the following spring batch job configuration. There is a single reader which then passes details to a composite writer which has two specific writers. Both writers share a common parent and need to use the same JobId for the INSERT operations they execute.
<bean id="job" parent="simpleJob">
<property name="steps">
<list>
<bean parent="simpleStep">
<property name="itemReader" ref="policyReader"/>
<property name="itemWriter" ref="stagingCompositeWriter"/>
</bean>
</list>
</property>
</bean>
<bean id="stagingCompositeWriter" class="org.springframework.batch.item.support.CompositeItemWriter">
<property name="delegates">
<list>
<ref bean="stagingLoadWriter"/>
<ref bean="stagingPolicyWriter"/>
</list>
</property>
</bean>
<bean id="abstractStagingWriter" class="a.b.c.AbstractStagingWriter" abstract="true">
<property name="stepExecution" value="#{stepExecutionContext}"/>
<property name="hedgingStagingDataSource" ref="hedgingStagingDataSource"/>
</bean>
<bean id="stagingLoadWriter" class="a.b.c.StagingLoadWriter" parent="abstractStagingWriter"/>
<bean id="stagingPolicyWriter" class="a.b.c.StagingPolicyWriter" parent="abstractStagingWriter"/>
When i run my code i get the following error
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'stepExecutionContext' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:208)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88)
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:139)
I have tried setting the scope="step" in various place but to no avail. Any suggestions?
You can access the stepExecutionContext only within a bean defined in the scope="step".
Change your bean definition to
<bean id="stagingLoadWriter" scope="step" class="a.b.c.StagingLoadWriter" parent="abstractStagingWriter" />
<bean id="stagingPolicyWriter" scope="step" class="a.b.c.StagingPolicyWriter" parent="abstractStagingWriter"/>

Heroku's Spring MVC Hibernate template application not connecting to DB

I'm trying to get the sample application running, but getting the following error when it tries to connect to the db:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
I haven't changed the applicationContext.xml, and the particular portion is:
<beans profile="default">
<jdbc:embedded-database id="dataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
</beans>
<beans profile="prod">
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{ 'jdbc:postgresql://' + #dbUrl.getHost() + #dbUrl.getPath() }"/>
<property name="username" value="#{ #dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ #dbUrl.getUserInfo().split(':')[1] }"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- change this to 'verify' before running as a production app -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
</beans>
I am able to connect to the db using pgAdmin III from my laptop.
Also, I am learning Spring, and I see some beans are wrapped in the profile "prod", but I cannot tell anywhere in code or web.xml that uses a particular profile.
Does the application server (Heroku?) need to start in a particular mode/profile, could that be why the db connection is not opening?
I'm learning Heroku as well.
Are you trying to run application on local machine? To be able to run this sample project on your local machine, you need to have database created. It's not described in the tutorial but if you try to use sample DATABASE_URL (postgres://scott:tiger#localhost/myapp) you need to create user scott with password tiger and create database myapp and grant scott required privileges. What I did, I've created sampledb database with existing postgres user, since it's database admin, I don't need to bother with grants and just changed url to
export DATABASE_URL=postgres://postrges:<password>#localhost/sampledb

Problems with Spring WS Streaming Attachments with Security Interceptor

I'm having problems getting Spring WS to receive a request which has a file attached and use streaming. The problem is I get the following exception whenever I try to use a security interceptor:
2011-01-11 15:10:05,132 DEBUG [org.springframework.ws.soap.server.SoapMessageDispatcher] -
java.lang.IllegalArgumentException: Error in converting SOAP Envelope to Document
at org.springframework.ws.soap.axiom.support.AxiomUtils.toDocument(AxiomUtils.java:135)
at org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor.toDocument(Wss4jSecurityInterceptor.java:621)
at org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor.validateMessage(Wss4jSecurityInterceptor.java:492)
at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleRequest(AbstractWsSecurityInterceptor.java:104)
at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:213)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:168)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:230)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:530)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:426)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:457)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:931)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:361)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:867)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:245)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113)
at org.eclipse.jetty.server.Server.handle(Server.java:337)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:581)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:1020)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:775)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:228)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:417)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:474)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:437)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.apache.axiom.om.OMException: java.util.NoSuchElementException
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:249)
at org.apache.axiom.om.impl.llom.OMNodeImpl.build(OMNodeImpl.java:327)
at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:706)
at org.springframework.ws.soap.axiom.support.AxiomUtils.toDocument(AxiomUtils.java:125)
... 34 more
Caused by: java.util.NoSuchElementException
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1083)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:506)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:161)
... 37 more
I am using the Axiom Message Factory:
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="false"/>
<property name="attachmentCaching" value="true"/>
<property name="attachmentCacheThreshold" value="1024" />
</bean>
My endpoint mapping uses the wss4jSecurityInterceptor:
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="mappings">
<props>
<prop key="{http://www.aquilauk.co.uk/hribulkupload}BulkHRRequest">hriBulkUploadEndpoint</prop>
</props>
</property>
<property name="interceptors">
<list>
<!-- <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/> -->
<ref bean="wss4jSecurityInterceptor"/>
</list>
</property>
</bean>
and my security interceptor has been set up to ensure it does not make use of the Payload:
<bean id="wss4jSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="UsernameToken" />
<property name="validationCallbackHandler" ref="springWSS4JHandler"/>
<property name="secureResponse" value="false"/>
<property name="secureRequest" value="false" />
</bean>
<bean id="acegiWSS4JHandler"
class="org.springframework.ws.soap.security.wss4j.callback.SpringPlainTextPasswordValidationCallbackHandler">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
Regard,
Craig
I believe that the security interceptor you have defined still consumes the payload. It just doesn't perform any security validation on it. The AxiomSoapMessageFactory.createWebServiceMesssage() method should be being called in order to create the MessageContext that is provided to the security interceptor. The security interceptor then ignores it as per the secureRequest flag.
I Found the solutions to this problem through trial and error:
The problem is the setup of the wss4jSecurityInterceptor, the lines:
<property name="secureResponse" value="false"/>
<property name="secureRequest" value="false" />
should have been:
<property name="validateRequest" value="false" />
<property name="validateResponse" value="false" />

How to initialize ConnectionFactory for remote JMS queue when remote machine is not running?

Using JBoss 4.0.5, JBossMQ, and Spring 2.0.8, I am trying to configure Spring to instantiate beans which depend on a remote JMS Queue resource. All of the examples I've come across depend on using JNDI to do lookup for things like the remote ConnectionFactory object.
My problem is when trying to bring up a machine which would put messages into the remote queue, if the remote machine is not up, JNDI lookup simply fails, causing deployment to fail. Is there a way to get Spring to keep trying to lookup this object in the background while not blocking the remainder of deployment?
Iit's difficult to be sure without seeing your spring config, but assuming you're using Spring's JndiObjectFactoryBean to do the JNDI lookup, then you can set the lookupOnStartup property to false, which allows the context to start up even if the JNDI target isn't there. The JNDI resolution will be done the first time the ConnectionFactory is used.
However, this just shifts the problem further up the chain, because if some other component tries to get a JMS Connection on startup, then you're back where you started. You can use the lazy-init="true" attribute on your other beans to prevent this from happening on deployment, but it's easy to accidentally put something in your config which forces everything to initialize.
You're absolutely right. I tried setting lookupOnStartup to false and lazy-init=true . This just defers the problem to the first time that the Queue is attempted to be used. Then an exception as follows is thrown:
[org.jboss.mq.il.uil2.SocketManager] Failed to handle: org.jboss.mq.il.uil2.msgs.CloseMsg29702787[msgType: m_connectionClosing, msgID: -2147483606, error: null]
java.io.IOException: Client is not connected
Moreover, it looks like the lookup is never attempted again. When the machine with the remote queue is brought back up, no messages are ever processed subsequently. This really does seem like it should be well within the envelope of use cases for J2EE nonsense, and yet I'm not having much luck... It feels like it should even maybe be a solved problem.
For completion's sake, the following is the pertinent portion of my Spring configuration.
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">localhost:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
</props>
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>ConnectionFactory</value>
</property>
</bean>
<bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate" lazy-init="true">
<property name="environment">
<props>
<prop key="java.naming.provider.url">jnp://10.0.100.232:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
</props>
</property>
</bean>
<bean id="remoteConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
<property name="jndiTemplate" ref="remoteJndiTemplate"/>
<property name="jndiName" value="ConnectionFactory" />
<property name="lookupOnStartup" value="false" />
<property name="proxyInterface" value="javax.jms.ConnectionFactory" />
</bean>
<bean id="destinationResolver" class="com.foo.jms.FooDestinationResolver" />
<bean id="localVoicemailTranscodingDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="queue/voicemailTranscoding" />
</bean>
<bean id="globalVoicemailTranscodingDestination" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true" >
<property name="jndiTemplate" ref="remoteJndiTemplate" />
<property name="jndiName" value="queue/globalVoicemailTranscoding" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestination" ref="localVoicemailTranscodingDestination" />
</bean>
<bean id="remoteJmsTemplate" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
<property name="connectionFactory" ref="remoteConnectionFactory"/>
<property name="destinationResolver" ref="destinationResolver"/>
</bean>
<bean id="globalQueueStatus" class="com.foo.bar.recording.GlobalQueueStatus" />
<!-- Do not deploy this bean for machines other than transcoding machine -->
<condbean:cond test="${transcoding.server}">
<bean id="voicemailMDPListener"
class="org.springframework.jms.listener.adapter.MessageListenerAdapter" lazy-init="true">
<constructor-arg>
<bean class="com.foo.bar.recording.mdp.VoicemailMDP" lazy-init="true">
<property name="manager" ref="vmMgr" />
</bean>
</constructor-arg>
</bean>
</condbean:cond>
<bean id="voicemailForwardingMDPListener"
class="org.springframework.jms.listener.adapter.MessageListenerAdapter" lazy-init="true">
<constructor-arg>
<bean class="com.foo.bar.recording.mdp.QueueForwardingMDP" lazy-init="true">
<property name="queueStatus" ref="globalQueueStatus" />
<property name="template" ref="remoteJmsTemplate" />
<property name="remoteDestination" ref="globalVoicemailTranscodingDestination" />
</bean>
</constructor-arg>
</bean>
<bean id="prototypeListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
abstract="true"
lazy-init="true">
<property name="concurrentConsumers" value="5" />
<property name="connectionFactory" ref="connectionFactory" />
<!-- 2 is CLIENT_ACKNOWLEDGE: http://java.sun.com/j2ee/1.4/docs/api/constant-values.html#javax.jms.Session.CLIENT_ACKNOWLEDGE -->
<!-- 1 is autoacknowldge -->
<property name="sessionAcknowledgeMode" value="1" />
<property name="sessionTransacted" value="true" />
</bean>
<!-- Do not deploy this bean for machines other than transcoding machine -->
<condbean:cond test="${transcoding.server}">
<bean id="voicemailMDPContainer" parent="prototypeListenerContainer" lazy-init="true">
<property name="destination" ref="globalVoicemailTranscodingDestination" />
<property name="messageListener" ref="voicemailMDPListener" />
</bean>
</condbean:cond>
<bean id="voicemailForwardMDPContainer" parent="prototypeListenerContainer" lazy-init="true">
<property name="destination" ref="localVoicemailTranscodingDestination" />
<property name="messageListener" ref="voicemailForwardingMDPListener" />
</bean>