You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Magnus Heino <ma...@filur.org> on 2008/02/08 09:42:50 UTC
Bug?
Hi.
I have XA transactions working now... but only using "pure" spring, not
camel.
My code looks like this now:
@Component("updateService")
public class UpdateServiceImpl implements UpdateService {
@EndpointInject(uri = "jms:queue:foobar")
private ProducerTemplate producer;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/*
* (non-Javadoc)
*
* @see
se.lantmateriet.origo.service.internal.UpdateService#handleMessage(
java.lang.String)
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleMessage(final String message) {
this.logger.info("Message received: '{}'", message);
}
/*
* This is triggered by a timer...
*/
public void send() {
this.logger.debug("Sending Jms message");
this.producer.sendBody("demo");
}
}
this:
<camel:camelContext />
<bean id="updateServiceListenerContainer" class="
org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="transactionManager" ref="transactionManager" />
<property name="sessionTransacted" value="true" />
<property name="destinationName" value="foobar" />
<property name="messageListener">
<bean class="
org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="updateService" />
</bean>
</property>
</bean>
Makes my bean consume messages in a xa transaction. Pending message count in
EMS is 0 when the queue is empty and the app is running, and it stays that
way when I shutdown jboss.
This config, which really does exactly the same thing afaik, fails:
<bean class="org.apache.camel.component.jms.JmsComponent">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="transactionManager" ref="transactionManager" />
<property name="transacted" value="true" />
</bean>
<camel:camelContext>
<camel:route>
<camel:from uri="jms:queue:foobar" />
<camel:to uri="bean:updateService" />
</camel:route>
</camel:camelContext>
Pending message count in EMS is 0 when the queue is empty and the app is
running, but when I shutdown jboss all messages that have been consumed are
back in ems, pending message size >0.
>From my non-expert view, it looks as if mssages are left unacknowledged in
EMS queue after camel has committed the transaction...?
--
/Magnus Heino
Re: Bug?
Posted by Magnus Heino <ma...@filur.org>.
Will XA and the setup I have also affect how erroHandling is done?
This:
errorHandler(loggingErrorHandler());
from("jms:queue:foobar").to("bean:updateService");
will try to deliver 5 times and then log and throw the message away.
This:
from("jms:queue:foobar").errorHandler(deadLetterChannel("jms:queue:DLQ")).to("bean:updateService");
tries to deliver 5 times then sends the message to the DQL jms queue.
But this:
errorHandler(deadLetterChannel("jms:queue:DLQ"));
from("jms:queue:foobar").to("bean:updateService");
tries to deliver 5 times, then throws the message away.. nothing is on the
dql. Why?
(bean:updateService throws a runtimeexception every time called).
So I guess my question really is how messages are put on the DLQ in the
example above, when using XA. Message is read, delivered, delivery failed,
transactoin rollback. New transaction, message is read, put on the DQL, and
commit. Or what? And then why isn't the global errorhandler inherited in the
last example?
Thanks,
/Magnus
Re: Bug?
Posted by James Strachan <ja...@gmail.com>.
On 08/02/2008, Magnus Heino <ma...@filur.org> wrote:
> >
> > Ah sorry! My bad - I'd missed that you'd not configured the
> > JmsComponent with an ID of "jms". DOH!
> >
>
> Well, http://activemq.apache.org/camel/jms.html does say "Basically you can
> configure as many JMS component instances as you wish and give them all
> unique names."... but I guess I was starring too much on the code examples
> to notice that :-P
Me too! :)
> Also all examples does use names that makes you think that the uris are
> predefined. That jdbc should be jdbc. Atleast that was my impression.
Yeah.
> > We've tried to minimise the amount of Spring XML configuration
> > required in Camel by adding some 'convention over configuration rules'
> > - but I guess sometimes this magic trips folks up.
> >
>
> Maybe you should do some more logging? "Endpoint for uri 'jms' not found,
> autocreating default JMSComponent instance.."... sounds like something that
> deserves a logger.info to me.
Yeah. BTW what does your log look like if you use DEBUG logging and
don't specify id="jms"?
> YAY! We got there in the end! :)
> >
>
> Yes. It does feel nice to have this working when I leave for the weekend.
> Thanks!!! :-)
Nice end to the week - lets share a virtual beer :)
> > So in summary; the main issue was not using the id="jms" for the JMS
> > component configuration - and it seems for XA that we cannot use the
> > CACHE_CONNECTION / CACHE_CONSUMER.
> >
>
> If this is the case then maybe atleast it should be on
> http://activemq.apache.org/camel/jms.html
Agreed. I've updated the wiki a bit with a warning of CACHE_NONE
http://cwiki.apache.org/CAMEL/jms.html
> the covers and injecting the ConnectionFactory itself maybe - which
> > could be a bit too much magic maybe?
>
>
> Not if you log the magic imho.
Yeah. Lets make sure we fix up the DEBUG logging to show what the
magic is doing...
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://open.iona.com
Re: Bug?
Posted by Magnus Heino <ma...@filur.org>.
>
> Ah sorry! My bad - I'd missed that you'd not configured the
> JmsComponent with an ID of "jms". DOH!
>
Well, http://activemq.apache.org/camel/jms.html does say "Basically you can
configure as many JMS component instances as you wish and give them all
unique names."... but I guess I was starring too much on the code examples
to notice that :-P
Also all examples does use names that makes you think that the uris are
predefined. That jdbc should be jdbc. Atleast that was my impression.
> We've tried to minimise the amount of Spring XML configuration
> required in Camel by adding some 'convention over configuration rules'
> - but I guess sometimes this magic trips folks up.
>
Maybe you should do some more logging? "Endpoint for uri 'jms' not found,
autocreating default JMSComponent instance.."... sounds like something that
deserves a logger.info to me.
YAY! We got there in the end! :)
>
Yes. It does feel nice to have this working when I leave for the weekend.
Thanks!!! :-)
> So in summary; the main issue was not using the id="jms" for the JMS
> component configuration - and it seems for XA that we cannot use the
> CACHE_CONNECTION / CACHE_CONSUMER.
>
If this is the case then maybe atleast it should be on
http://activemq.apache.org/camel/jms.html
the covers and injecting the ConnectionFactory itself maybe - which
> could be a bit too much magic maybe?
Not if you log the magic imho.
--
/Magnus Heino
Re: Bug?
Posted by James Strachan <ja...@gmail.com>.
On 08/02/2008, Magnus Heino <ma...@filur.org> wrote:
> >
> > > It seems as if I am missing something fundamental here? I feel the smell
> > of
> > > a new user rtfm problem, but where is it? :)
> >
> > :) No I think there maybe some MessageListenerContainer configuration
> > gremlin you're hitting (though its really bizarre that things work
> > fine for JMS transactions, but not when switching to XA!)
> >
> > Camel tries its best to setup the various Spring objects right for you
> > without you having to set zillions of properties up; but maybe there's
> > some gremlin in there that needs fixing...
> >
> >
> > > How is my JmsComponent looked up by camel?
> >
> > So the CamelContext looks up in the Spring AppContext to see if
> > there's an endpoint for the URI, if not it takes the URI scheme (e.g.
> > jms) and looks up if there's a Component registered for that name and
> > uses that component to create the endpoint.
>
>
> So my JmsComponent needs to be named jms? My was unnamed i.e. I didn't
> provide a spring id.
Ah sorry! My bad - I'd missed that you'd not configured the
JmsComponent with an ID of "jms". DOH!
We've tried to minimise the amount of Spring XML configuration
required in Camel by adding some 'convention over configuration rules'
- but I guess sometimes this magic trips folks up.
> If I give my JmsComponent instance in spring the id "jms", I get these
> errors; Notice the Message received: 'demo' in the beginning, messages are
> consumed now, they are removed from ems too, even when I shutdown JBoss.
>
> 15:06:24,812 INFO [Server] JBoss (MX MicroKernel) [4.2.2.GA (build:
> SVNTag=JBoss_4_2_2_GA date=200710221139)] Started in 12s:408ms
> 15:06:24,859 INFO [STDOUT] 2008-02-08 15:06:24,859
> [DefaultMessageListenerContainer-1] INFO Message received: 'demo' at
> se.lantmateriet.origo.service.internal.UpdateServiceImpl.handleMessage(
> UpdateServiceImpl.java:34)
> 15:06:24,890 INFO [STDOUT] 2008-02-08 15:06:24,890
> [DefaultMessageListenerContainer-2] ERROR Setup of JMS message listener
> invoker failed - trying to recover at
> org.springframework.jms.listener.DefaultMessageListenerContainer.handleListenerSetupFailure
> (DefaultMessageListenerContainer.java:671)
> javax.jms.IllegalStateException: The connection is closed
> at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.checkClosed(
> JmsSessionFactoryImpl.java:413)
> at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.createSession(
> JmsSessionFactoryImpl.java:368)
> at org.springframework.jms.support.JmsAccessor.createSession(
> JmsAccessor.java:200)
> at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.access$200
> (AbstractPollingMessageListenerContainer.java:76)
> at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer$MessageListenerContainerResourceFactory.createSession
> (AbstractPollingMessageListenerContainer.java:477)
> at
> org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession
> (ConnectionFactoryUtils.java:282)
> at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute
> (AbstractPollingMessageListenerContainer.java:279)
> at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute
> (AbstractPollingMessageListenerContainer.java:235)
> at
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener
> (DefaultMessageListenerContainer.java:887)
> at
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run
> (DefaultMessageListenerContainer.java:822)
> at java.lang.Thread.run(Thread.java:595)
> 15:06:24,906 INFO [STDOUT] 2008-02-08 15:06:24,906
> [DefaultMessageListenerContainer-2] INFO Successfully refreshed JMS
> Connection at
> org.springframework.jms.listener.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful
> (DefaultMessageListenerContainer.java:712)
>
> If I add <property name="cacheLevelName" value="CACHE_NONE" />, things seems
> to work!!!!! :-)
YAY! We got there in the end! :)
So in summary; the main issue was not using the id="jms" for the JMS
component configuration - and it seems for XA that we cannot use the
CACHE_CONNECTION / CACHE_CONSUMER.
I guess when we are auto-creating the JMSComponent, we could be nice
and look in spring.xml and see if there's a single bean available of
type JMSComponent and if so, use that. But maybe thats a step too far
in the level of magic?
But then I guess camel was just creating a default JMSComponent under
the covers and injecting the ConnectionFactory itself maybe - which
could be a bit too much magic maybe?
> I guess so, but I don't understand if this is expected behaviour, or a bug?
> :)
I didn't realise CACHE_NONE was mandatory for XA based JMS with
Spring. I guess we can make that the default to avoid others hitting
this bug...
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://open.iona.com
Re: Bug?
Posted by Magnus Heino <ma...@filur.org>.
>
> > It seems as if I am missing something fundamental here? I feel the smell
> of
> > a new user rtfm problem, but where is it? :)
>
> :) No I think there maybe some MessageListenerContainer configuration
> gremlin you're hitting (though its really bizarre that things work
> fine for JMS transactions, but not when switching to XA!)
>
> Camel tries its best to setup the various Spring objects right for you
> without you having to set zillions of properties up; but maybe there's
> some gremlin in there that needs fixing...
>
>
> > How is my JmsComponent looked up by camel?
>
> So the CamelContext looks up in the Spring AppContext to see if
> there's an endpoint for the URI, if not it takes the URI scheme (e.g.
> jms) and looks up if there's a Component registered for that name and
> uses that component to create the endpoint.
So my JmsComponent needs to be named jms? My was unnamed i.e. I didn't
provide a spring id.
If I give my JmsComponent instance in spring the id "jms", I get these
errors; Notice the Message received: 'demo' in the beginning, messages are
consumed now, they are removed from ems too, even when I shutdown JBoss.
15:06:24,812 INFO [Server] JBoss (MX MicroKernel) [4.2.2.GA (build:
SVNTag=JBoss_4_2_2_GA date=200710221139)] Started in 12s:408ms
15:06:24,859 INFO [STDOUT] 2008-02-08 15:06:24,859
[DefaultMessageListenerContainer-1] INFO Message received: 'demo' at
se.lantmateriet.origo.service.internal.UpdateServiceImpl.handleMessage(
UpdateServiceImpl.java:34)
15:06:24,890 INFO [STDOUT] 2008-02-08 15:06:24,890
[DefaultMessageListenerContainer-2] ERROR Setup of JMS message listener
invoker failed - trying to recover at
org.springframework.jms.listener.DefaultMessageListenerContainer.handleListenerSetupFailure
(DefaultMessageListenerContainer.java:671)
javax.jms.IllegalStateException: The connection is closed
at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.checkClosed(
JmsSessionFactoryImpl.java:413)
at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.createSession(
JmsSessionFactoryImpl.java:368)
at org.springframework.jms.support.JmsAccessor.createSession(
JmsAccessor.java:200)
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.access$200
(AbstractPollingMessageListenerContainer.java:76)
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer$MessageListenerContainerResourceFactory.createSession
(AbstractPollingMessageListenerContainer.java:477)
at
org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession
(ConnectionFactoryUtils.java:282)
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute
(AbstractPollingMessageListenerContainer.java:279)
at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute
(AbstractPollingMessageListenerContainer.java:235)
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener
(DefaultMessageListenerContainer.java:887)
at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run
(DefaultMessageListenerContainer.java:822)
at java.lang.Thread.run(Thread.java:595)
15:06:24,906 INFO [STDOUT] 2008-02-08 15:06:24,906
[DefaultMessageListenerContainer-2] INFO Successfully refreshed JMS
Connection at
org.springframework.jms.listener.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful
(DefaultMessageListenerContainer.java:712)
If I add <property name="cacheLevelName" value="CACHE_NONE" />, things seems
to work!!!!! :-)
> Did any of that help? :)
I guess so, but I don't understand if this is expected behaviour, or a bug?
:)
Thanks!!
/Magnus
Re: Bug?
Posted by James Strachan <ja...@gmail.com>.
On 08/02/2008, Magnus Heino <ma...@filur.org> wrote:
> >
> > If you don't mind helping debug it (which would be awesome BTW!), I
> > guess you could set a breakpoint in the
> > JmsConfiguration.createMessageListenerContainer() and see what
> > MessageListenerContainer is created by Camel and how its configured -
> > to see if there's any real difference at all in how Camel configures
> > it to how you've configured it explicitly? That must be the problem I
> > guess?
>
>
> Well, the container returned from
> JmsConfiguration.createMessageListenerContainer() seems to be the default
> one. That explains why it works in non-ax with jmstransactionmanager, since
> the default is autoack, right?
It should be using transacted mode which uses SessionTransacted rather
than AutoAck. DefaultMessageListenerContainer is usable with XA right?
You're using it directly with the sessionTransacted set to true? Camel
should be setting the same property too right?
i.e. I wonder if this bug is somehow related to Camel not setting all
the same properties (or setting more properties) than your pure Spring
example.
e.g. Camel should by default be setting sessionTransacted to be true
and setting the sessionAcknowledgement mode to
Session.SESSION_TRANSACTED. I wonder if Spring gets confused if we set
that?
Or maybe its an issue with caching? By default in 1.2.0 we use
CACHE_CONNECTION due to a Spring bug; in trunk of Camel with Spring
2.5.1 we now set CACHE_CONSUMER by default.
Maybe explicitly setting CACHE_NONE in the Camel example works for
TibCo EMS with XA?
> It seems as if I am missing something fundamental here? I feel the smell of
> a new user rtfm problem, but where is it? :)
:) No I think there maybe some MessageListenerContainer configuration
gremlin you're hitting (though its really bizarre that things work
fine for JMS transactions, but not when switching to XA!)
Camel tries its best to setup the various Spring objects right for you
without you having to set zillions of properties up; but maybe there's
some gremlin in there that needs fixing...
> How is my JmsComponent looked up by camel?
So the CamelContext looks up in the Spring AppContext to see if
there's an endpoint for the URI, if not it takes the URI scheme (e.g.
jms) and looks up if there's a Component registered for that name and
uses that component to create the endpoint.
> Right now it's just registered in
> the spring application context, I was assuming that you had some
> beanprocessor looking for components, and registering them with camel?
Its more a case of when a route is activated, the URIs used in the
route are resolved by the CamelContext which tends to delegate to the
Spring AppContext to try figure out what they are etc.
Did any of that help? :)
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://open.iona.com
Re: Bug?
Posted by Magnus Heino <ma...@filur.org>.
>
> If you don't mind helping debug it (which would be awesome BTW!), I
> guess you could set a breakpoint in the
> JmsConfiguration.createMessageListenerContainer() and see what
> MessageListenerContainer is created by Camel and how its configured -
> to see if there's any real difference at all in how Camel configures
> it to how you've configured it explicitly? That must be the problem I
> guess?
Well, the container returned from
JmsConfiguration.createMessageListenerContainer() seems to be the default
one. That explains why it works in non-ax with jmstransactionmanager, since
the default is autoack, right?
It seems as if I am missing something fundamental here? I feel the smell of
a new user rtfm problem, but where is it? :)
How is my JmsComponent looked up by camel? Right now it's just registered in
the spring application context, I was assuming that you had some
beanprocessor looking for components, and registering them with camel?
--
/Magnus Heino
Re: Bug?
Posted by James Strachan <ja...@gmail.com>.
On 08/02/2008, Magnus Heino <ma...@filur.org> wrote:
> >
> >
> >
> > Are you totally positive you are using exactly the same transaction
> > manager and JMS connection factory in both cases?
>
>
> Yes, 101%.
>
> This is my applicationContext.xml
>
> I run it as it is right now, and it fails. Messages are back in ems when I
> shutdown jboss.
>
> I then uncomment the empty camelcontext and DefaultMessageListenerContainer,
> comment out the camelcontext with the route and JmsComponent, clean build
> and redeploy, start jboss, consume a few messages, shutdown, no messages are
> now in ems.
>
> I can do this over and over again, the only change is in this file, and the
> behaviour is the same all the time.
>
> This is 1.2.0, same thing happens with 1.3-SNAPSHOT.
>
> I have eclipse setup with sourcecode, so it's easy for me to debug. And tip
> on where I should look?
>
> <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="
> http://www.springframework.org/schema/tx"
> xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="
> http://www.springframework.org/schema/jee"
> xmlns:context="http://www.springframework.org/schema/context"
> xmlns:camel="http://activemq.apache.org/camel/schema/spring"
> xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
> http://www.springframework.org/schema/aop
> http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
> http://www.springframework.org/schema/tx
> http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
> http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-2.5.xsd
> http://www.springframework.org/schema/jee
> http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
> http://www.springframework.org/schema/context
> http://www.springframework.org/schema/context/spring-context-2.5.xsd
> http://activemq.apache.org/camel/schema/spring
> http://activemq.apache.org/camel/schema/spring/camel-spring-1.2.0.xsd
> "
> default-autowire="no">
>
> <context:component-scan base-package="se.lantmateriet.origo" />
>
> <tx:annotation-driven />
>
> <tx:jta-transaction-manager />
>
> <jee:jndi-lookup id="jmsConnectionFactory"
> jndi-name="java:jms/jmsConnectionFactory" />
>
> <!--
> <camel:camelContext />
>
> <bean id="updateServiceListenerContainer" class="
> org.springframework.jms.listener.DefaultMessageListenerContainer">
> <property name="concurrentConsumers" value="1" />
> <property name="connectionFactory" ref="jmsConnectionFactory" />
> <property name="transactionManager" ref="transactionManager" />
> <property name="sessionTransacted" value="true" />
> <property name="destinationName" value="foobar" />
> <property name="messageListener">
> <bean class="
> org.springframework.jms.listener.adapter.MessageListenerAdapter">
> <constructor-arg ref="updateService" />
> </bean>
> </property>
> </bean>
> -->
> <camel:camelContext>
> <camel:route>
> <camel:from uri="jms:queue:foobar" />
> <camel:to uri="bean:updateService" />
> </camel:route>
> </camel:camelContext>
>
> <bean class="org.apache.camel.component.jms.JmsComponent">
> <property name="concurrentConsumers" value="1" />
> <property name="connectionFactory" ref="jmsConnectionFactory" />
> <property name="transactionManager" ref="transactionManager" />
> <property name="transacted" value="true" />
> </bean>
>
> <bean id="scheduledTask" class="
> org.springframework.scheduling.timer.ScheduledTimerTask">
> <!-- wait 5 seconds before starting repeated execution -->
> <property name="delay" value="5000" />
> <!-- run every 5 seconds -->
> <property name="period" value="5000" />
> <property name="timerTask">
> <bean id="doIt" class="
> org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
> <property name="targetObject" ref="updateService" />
> <property name="targetMethod" value="send" />
> </bean>
> </property>
> </bean>
>
> <bean id="timerFactory" class="
> org.springframework.scheduling.timer.TimerFactoryBean">
> <property name="scheduledTimerTasks">
> <list>
> <!-- see the example above -->
> <ref bean="scheduledTask" />
> </list>
> </property>
> </bean>
>
> </beans>
Damn :)
If you don't mind helping debug it (which would be awesome BTW!), I
guess you could set a breakpoint in the
JmsConfiguration.createMessageListenerContainer() and see what
MessageListenerContainer is created by Camel and how its configured -
to see if there's any real difference at all in how Camel configures
it to how you've configured it explicitly? That must be the problem I
guess?
All the JmsConsumer does in Camel is create the
MessageListenerContainer, set the MessageListener on it to process the
message via Camel then start the container and Spring does the rest.
BTW do the JMS messages on the queue have the JMSReplyTo header set?
Only if it has then Camel by default will try and send a reply back
(am just wondering if this might have an effect). You can disable it
via the "disableReplyTo" property on the endpoint URI
http://cwiki.apache.org/CAMEL/jms.html
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://open.iona.com
Re: Bug?
Posted by Magnus Heino <ma...@filur.org>.
>
>
>
> Are you totally positive you are using exactly the same transaction
> manager and JMS connection factory in both cases?
Yes, 101%.
This is my applicationContext.xml
I run it as it is right now, and it fails. Messages are back in ems when I
shutdown jboss.
I then uncomment the empty camelcontext and DefaultMessageListenerContainer,
comment out the camelcontext with the route and JmsComponent, clean build
and redeploy, start jboss, consume a few messages, shutdown, no messages are
now in ems.
I can do this over and over again, the only change is in this file, and the
behaviour is the same all the time.
This is 1.2.0, same thing happens with 1.3-SNAPSHOT.
I have eclipse setup with sourcecode, so it's easy for me to debug. And tip
on where I should look?
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="
http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="
http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:camel="http://activemq.apache.org/camel/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring-1.2.0.xsd
"
default-autowire="no">
<context:component-scan base-package="se.lantmateriet.origo" />
<tx:annotation-driven />
<tx:jta-transaction-manager />
<jee:jndi-lookup id="jmsConnectionFactory"
jndi-name="java:jms/jmsConnectionFactory" />
<!--
<camel:camelContext />
<bean id="updateServiceListenerContainer" class="
org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="transactionManager" ref="transactionManager" />
<property name="sessionTransacted" value="true" />
<property name="destinationName" value="foobar" />
<property name="messageListener">
<bean class="
org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="updateService" />
</bean>
</property>
</bean>
-->
<camel:camelContext>
<camel:route>
<camel:from uri="jms:queue:foobar" />
<camel:to uri="bean:updateService" />
</camel:route>
</camel:camelContext>
<bean class="org.apache.camel.component.jms.JmsComponent">
<property name="concurrentConsumers" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="transactionManager" ref="transactionManager" />
<property name="transacted" value="true" />
</bean>
<bean id="scheduledTask" class="
org.springframework.scheduling.timer.ScheduledTimerTask">
<!-- wait 5 seconds before starting repeated execution -->
<property name="delay" value="5000" />
<!-- run every 5 seconds -->
<property name="period" value="5000" />
<property name="timerTask">
<bean id="doIt" class="
org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="updateService" />
<property name="targetMethod" value="send" />
</bean>
</property>
</bean>
<bean id="timerFactory" class="
org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<!-- see the example above -->
<ref bean="scheduledTask" />
</list>
</property>
</bean>
</beans>
--
/Magnus Heino
Re: Bug?
Posted by James Strachan <ja...@gmail.com>.
On 08/02/2008, Magnus Heino <ma...@filur.org> wrote:
> Hi.
>
> I have XA transactions working now... but only using "pure" spring, not
> camel.
>
> My code looks like this now:
>
> @Component("updateService")
> public class UpdateServiceImpl implements UpdateService {
>
> @EndpointInject(uri = "jms:queue:foobar")
> private ProducerTemplate producer;
>
> private final Logger logger = LoggerFactory.getLogger(this.getClass());
>
> /*
> * (non-Javadoc)
> *
> * @see
> se.lantmateriet.origo.service.internal.UpdateService#handleMessage(
> java.lang.String)
> */
> @Transactional(propagation = Propagation.REQUIRES_NEW)
> public void handleMessage(final String message) {
> this.logger.info("Message received: '{}'", message);
> }
>
> /*
> * This is triggered by a timer...
> */
> public void send() {
> this.logger.debug("Sending Jms message");
> this.producer.sendBody("demo");
> }
> }
>
>
>
> this:
>
> <camel:camelContext />
>
> <bean id="updateServiceListenerContainer" class="
> org.springframework.jms.listener.DefaultMessageListenerContainer">
> <property name="concurrentConsumers" value="1" />
> <property name="connectionFactory" ref="jmsConnectionFactory" />
> <property name="transactionManager" ref="transactionManager" />
> <property name="sessionTransacted" value="true" />
> <property name="destinationName" value="foobar" />
> <property name="messageListener">
> <bean class="
> org.springframework.jms.listener.adapter.MessageListenerAdapter">
> <constructor-arg ref="updateService" />
> </bean>
> </property>
> </bean>
>
> Makes my bean consume messages in a xa transaction. Pending message count in
> EMS is 0 when the queue is empty and the app is running, and it stays that
> way when I shutdown jboss.
>
> This config, which really does exactly the same thing afaik, fails:
>
> <bean class="org.apache.camel.component.jms.JmsComponent">
> <property name="concurrentConsumers" value="1" />
> <property name="connectionFactory" ref="jmsConnectionFactory" />
> <property name="transactionManager" ref="transactionManager" />
> <property name="transacted" value="true" />
> </bean>
>
> <camel:camelContext>
> <camel:route>
> <camel:from uri="jms:queue:foobar" />
> <camel:to uri="bean:updateService" />
> </camel:route>
> </camel:camelContext>
>
> Pending message count in EMS is 0 when the queue is empty and the app is
> running, but when I shutdown jboss all messages that have been consumed are
> back in ems, pending message size >0.
>
> From my non-expert view, it looks as if mssages are left unacknowledged in
> EMS queue after camel has committed the transaction...?
Thanks for your test case, this is great. I confess to being a little
stumped, as under the covers the Camel component is pretty much doing
exactly the same thing as you are doing via pure Spring - using the
DefaultMessageListenerContainer to do all the heavy lifting.
Its also kinda bizarre that things work for you fine using Camel with
the JMS transaction manager - but as soon as you switch to using XA it
doesn't work.
Are you totally positive you are using exactly the same transaction
manager and JMS connection factory in both cases?
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://open.iona.com