Unable to proxy a JBossMQ queue in Spring - spring

Spring JMS going against a JBoss 4.x JBossMQ queue (I know, old JBoss, JBossMQ superseded by JBoss Messaging, but I can't change the stack). Everything works when the Spring JMS configuration is loaded at startup, but when I make the JNDI lookups lazy, so that they are first loaded when I want to send a JMS message, I get the following exception:
org.springframework.jms.InvalidDestinationException: Destination is not an instance of SpyDestination QUEUE.myQueueName; nested exception is javax.jms.InvalidDestinationException: Destination is not an instance of SpyDestination QUEUE.myQueueName
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:285)
My config:
<jee:jndi-lookup id="beanNameForMyQueue"
jndi-name="queue/myQueueName"
resource-ref="true" environment-ref="jndiEnvironment"
lookup-on-startup="false" cache="true" proxy-interface="javax.jms.Queue" />
I found a JBoss JIRA on this, and this similar HornetQ post, but so far no dice.
Am I just out of luck with the lazy init, or is there a workaround?

Related

Connecting ActiveMQ Web-Console to an existing broker (instead of starting a new one)

Having deployed the activemq-web-console war into a Tomcat embedded application how can one make it connect to an existing broker rather than create a new one?
The war comes with a set of predefined configurations, in particular, the WEB-INF/activemq.xml contains a configuration for the BrokerService
<broker brokerName="web-console" useJmx="true" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter><kahaDB directory="target/kahadb"/></persistenceAdapter>
<transportConnectors>
<transportConnector uri="tcp://localhost:12345"/>
</transportConnectors>
</broker>
used from webconsole-embedded.xml in the following manner:
<bean id="brokerService" class="org.apache.activemq.xbean.BrokerFactoryBean">
<property name="config" value="/WEB-INF/activemq.xml"/>
</bean>
This configuration creates a new instance of BrokerService and tries to start the broker.
It is reported that the web console can be used to monitor an existing broker service rather than creating a new one. For this one should set the following properties somewhere:
webconsole.type=properties
webconsole.jms.url=tcp://localhost:61616
webconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-trun
The questions is, where does one have to set these properties within the Tomcat embedded app and which XML changes in the above have to be performed for them to be used. I cannot find any sensible explanation how to configure it, and a BrokerService instance seems to be required by the remaining spring config.
Any ideas?
Please do not suggest to use hawtio instead!
I had the same problem today. You can start the webconsole in "properties" mode which gives you the oppertunity to connect over jmx.
I added following java arguments to our Jboss 6.1 and it worked immediatley. I didn't change any of the xmls (works out of the box)...
Example:
-Dwebconsole.type=properties -Dwebconsole.jms.url=tcp://<hostname>:61616 -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://<hostname>:1090/jmxrmi -Dwebconsole.jmx.user=admin -Dwebconsole.jmx.password=123456
Also discussed here: https://svn.apache.org/repos/infra/websites/production/activemq/content/5.7.0/web-console.html

How to set up Eclipselink cache coordination with Wildfly

I have set up a persistancce caching with Eclipselink on Wildfly 8. It works, but I also want to do cache coordination. I have the following setup for Eclipselink cache coordination in my persistance.xml:
<property name="eclipselink.cache.coordination.protocol" value="jms" />
<property name="eclipselink.cache.coordination.jms.topic" value="jms/MemberTopic" />
<property name="eclipselink.cache.coordination.jms.factory" value="jms/MemberConnectionFactory" />
However, when my entity is merged, no messages are sent by Eclipselink. I have logging set to "ALL", but nothing appears in the console.
I tried adding coordinationType=CacheCoordinationType.SEND_NEW_OBJECTS_WITH_CHANGES to entity's #Cache annotation, but it doesn't change anything. Also tried using an MDB as suggested for WebSphere (http://www.eclipse.org/eclipselink/documentation/2.4/concepts/cache011.htm#CDECEHFH).
The JMS topic and connectionfactory exist and Wildfly startup / application deployment shows no errors. For server clustering I run Wildfly in domain mode.
The problem ironically was in my Wildfly configuration instead - I didn't have my messaging cluster set up. I used the default messaging cluster settings from full-ha profile and set Eclipselink's cache coordination host accordingly:
<property name="eclipselink.cache.coordination.jms.host" value="231.7.7.7:9876" />

Redelivering Activemq messages after consumer throws exception

I have a spring application with a consumer to consume messages and write them to a database. I'm using the spring DefaultMessageListenerContainer. Is there a way to consume a message and upon a database exception being thrown put the message back onto the queue?
setSessionTransacted(true)
If you are using the namespace to configure the container, use
<jms:listener-container acknowledge="transacted" ...>
<jms:listener ... />
</jms:listener-container>
You also might want to synchronize the database and JMS transactions by adding the JDBC transaction manager to the container configuration.
See Dave Syer's Javaworld Article about Distributed transactions in Spring, with and without XA

How to detect loss of JMS Topic connection

We have swing GUI clients that are connecting to a server process.
The clients 'call' services on the server using jms:queue 'from' endpoints defined in Camel routes, and using ActiveMQ as the underlying JMS broker.
However, the client also offers a Camel jms:topic endpoint for the server to broadcast messages back to the client.
Unfortunately, it looks like the topic connection is getting lost somehow, and although the client can still 'call' the services on the server, the server cannot send any messages to the client's topic endpoint.
The client-side spring definition of the Camel endpoint is as follows:
<camel:route>
<camel:from uri="jms:topic:inUseQueue"/>
<camel:to uri="bean:inUseInterfaceImpl"/>
</camel:route>
And the server-side producer is defined as follows:
<bean id="inUseManagerImpl" class="org.apache.camel.spring.remoting.CamelProxyFactoryBean">
<property name="serviceUrl" value="jms:topic:inUseQueue"/>
<property name="serviceInterface" value="uniworks.core.inuse.InUseInterface"/>
</bean>
Does anyone know of a way that we can somehow detect the loss of this topic connection on the client side?
An easy workaround shall be to override isSingleton() method of CamelProxyFactoryBean. Return false and let spring create the producer bean on every invocation instead of caching it. Or you can also define the scope of CamelProxyFactoryBean to be prototype.
Also you can try with the ActiveMQ camel component that supports connection pooling.
I realize this is a 8 month old question, but hey what the hell.
would it make sense to make the server broadcast "isalive" message once a minute, this way if the client doesn't get any of the "isalive" messages it can presume it has been disconnected.

how to get XADatasource using JNDI look up for Atomikos Transaction Management

I am configuring Atomikios TM API with my Spring Application to achieve global transaction. As Atomikios require XADatasource to work, so I have done JNDI look up to get the same. But, unfortunately I am getting following errors while doing the look up.
Object of type [class com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource] available at JNDI location [jdbc/cuds] is not assignable to [javax.sql.XADataSource]
<jee:jndi-lookup id="dataSourceCu" jndi-name="jdbc/cuds" cache="true" resource-ref="true" lookup-on-startup="true" expected-type="javax.sql.XADataSource" />
<jee:jndi-lookup id="dataSourceGodb" jndi-name="jdbc/pushpullds" cache="true" resource-ref="true" lookup-on-startup="true" expected-type="javax.sql.XADataSource" />
I am using Spring 3.0/ hibernate with WebSphere 7.0.Where I am doing wrong. Please help me. Thanks.
The data source configured under jdbc/cuds is not an XADataSource but a normal one. You need to change the data source configuration in WebSphere (I have no idea how to do this).
However since you're on WebSphere which has it's own transaction manager there really is no need for configuring Atomikios. You can either use
<tx:jta-transaction-manager>
or org.springframework.transaction.jta.JtaTransactionManager / org.springframework.transaction.jta.WebSphereUowTransactionManager but the data source still needs to be XA.
XADataSource defines a contract between a JDBC provider and the application server and can only be used in that context. The DataSource object that you get when looking up the data source via JNDI in your application will never implement the XADataSource interface, even if the underlying data source is configured to support XA.
If you want to use your own transaction manager, then you would also have to manage the data sources yourself. Note that personally I wouldn't do that and strongly advice to use WebSphere's transaction manager instead. The reason is that distributed transactions involve lots of subtleties (e.g. recovery and in-doubt transactions) and it is unlikely that setting up a transaction manager inside an application would achieve the same level of robustness as WebSphere's transaction manager.

Resources