Announcement Announcement Module
Collapse
No announcement yet.
jms-source cannot be configured with a jms-template Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • jms-source cannot be configured with a jms-template

    Hello,

    I am working on a Spring Integration (1.0.0m1) sample that uses both a jms-target and a jms-source in my configuration. Even though the spring-integration.xsd for 1.0.0m1 states that both jms-target and jms-source can be configured with a jms-template attribute, I get an error if I try to configure a jms-template on a jms-source node. However, I am able to configure a jms-template on a jms-target. This behavior seems inconsistent.

    Snippet from spring-integration.xsd (1.0.0m1):

    <xsd:element name="jms-source">
    <xsd:complexType>
    <xsd:annotation>
    <xsd:documentation>
    Defines a jms-based source channel adapter.
    </xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="id" type="xsd:string"/>
    <xsd:attribute name="jms-template" type="xsd:string"/>
    <xsd:attribute name="connection-factory" type="xsd:string"/>
    <xsd:attribute name="destination" type="xsd:string"/>
    <xsd:attribute name="destination-name" type="xsd:string"/>
    <xsd:attribute name="channel" type="xsd:string" use="required"/>
    <xsd:attribute name="poll-period" type="xsd:int"/>
    </xsd:complexType>
    </xsd:element>

    <xsd:element name="jms-target">
    <xsd:complexType>
    <xsd:annotation>
    <xsd:documentation>
    Defines a jms-based target channel adapter.
    </xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="id" type="xsd:string"/>
    <xsd:attribute name="jms-template" type="xsd:string"/>
    <xsd:attribute name="connection-factory" type="xsd:string"/>
    <xsd:attribute name="destination" type="xsd:string"/>
    <xsd:attribute name="channel" type="xsd:string" use="required"/>
    </xsd:complexType>
    </xsd:element>
    In my configuration for SpringIntegration both of these things should be possible:

    this works:

    <jms-target id="fooJmsProvider"
    channel="fooJmsProviderChannel" jms-template="someJmsTemplate" />
    this fails:

    <jms-source id="fooJmsConsumer"
    channel="fooJmsConsumerChannel" jms-template="someOtherJmsTemplate" />
    The actual failure message is this:

    org.springframework.beans.factory.BeanDefinitionSt oreException: Unexpected exception parsing XML document from class path resource [/spring/swiftAdapterServiceDemo.xml]; nested exception is org.springframework.beans.factory.BeanCreationExce ption: JmsMessageDrivenSourceAdapter does not accept a 'jms-template' reference, both 'connection-factory' and 'destination' (or 'destination-name') must be provided.
    at org.springframework.beans.factory.xml.XmlBeanDefin itionReader.doLoadBeanDefinitions(XmlBeanDefinitio nReader.java:405)
    at org.springframework.beans.factory.xml.XmlBeanDefin itionReader.loadBeanDefinitions(XmlBeanDefinitionR eader.java:327)
    at org.springframework.beans.factory.xml.XmlBeanDefin itionReader.loadBeanDefinitions(XmlBeanDefinitionR eader.java:295)
    at org.springframework.beans.factory.support.Abstract BeanDefinitionReader.loadBeanDefinitions(AbstractB eanDefinitionReader.java:143)
    at org.springframework.context.support.AbstractXmlApp licationContext.loadBeanDefinitions(AbstractXmlApp licationContext.java:108)
    at org.springframework.context.support.AbstractXmlApp licationContext.loadBeanDefinitions(AbstractXmlApp licationContext.java:79)
    I need to use a Spring jmsTemplate to leverage the power of a messageConverter on my reply messages.

    Thanks,

    Brad

  • #2
    Brad,

    The "jms-template" attribute is only available when creating a JmsPollingSourceAdapter, and that requires the inclusion of the "poll-period" attribute as well. If the "poll-period" is not provided, then a JmsMessageDrivenSourceAdapter is created (typically a better choice), and it delegates to a DefaultMessageListenerContainer instead of using JmsTemplate.

    It turns out that the JmsMessageDrivenSourceAdapter does in fact provide a setMessageConverter() method, but it is not currently supported by the namespace driven configuration. I will create a Jira issue for M2. In the meantime, you should be able to provide the following configuration (notice the 'messageConverter' property):
    Code:
    <bean id="fooJmsConsumer" class="org.springframework.integration.adapter.jms.JmsMessageDrivenSourceAdapter">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destinationName" value="queue.foo"/>
        <property name="channel" ref="fooJmsConsumerChannel"/>
        <property name="messageConverter" ref="fooConverter"/>
    </bean>
    Hope that helps,
    Mark

    Comment


    • #3
      Here is the link to the Jira issue for the inclusion of the 'message-converter' attribute in case you would like to track the progress: http://jira.springframework.org/browse/INT-102

      -Mark

      Comment


      • #4
        The 'message-converter' ref is now available on <jms-source> when configuring a message-driven JMS adapter. If you get a chance, please try it out.

        -Mark

        Comment


        • #5
          message-converter on jms-source not working

          Hi Mark,

          I built the SI code from svn , and I see that message-converter is now supported in <jms-source> namespace as follows :
          <jms-source id="wmqConsumer2"
          connection-factory="connectionFactoryWMQ"
          destination-name="A.B.REQUEST"
          message-converter="messageConverter"
          channel="MyRequestChannel"/>

          <beans:bean id="messageConverter" class="com.my.IncomingMessageConverter"/>

          Still, the message converter is not being invoked when the message is read from the queue.. What am I missing ?

          Comment


          • #6
            That configuration looks correct. Can you post an excerpt with your message converter's fromMessage method?

            -Mark

            Comment


            • #7
              message-converter code

              Here is the code excerpt :<maybe I should be using fromMessage ..let me try >
              Code:
              public class IncomingMessageConverter extends SimpleMessageConverter {
              	
              	private static Log log = LogFactory.getLog(IncomingMessageConverter.class);
              	
              	/**
              	 * This message conversion manually acknowledges the receipt of the message so that JMS Provider will purge the message from the queue.
              	 */
              
              	public Message toMessage(Object o, Session s) throws JMSException, MessageConversionException {
              		log.debug("Using IncomingMessageConverter on request message.");
              		Message message = super.toMessage(o, s);
              		// manually acknowledge the message:
              		log.info("Manually acknowledging the reply message.");
              		message.acknowledge();
              		return message;
              	}	
              }
              Last edited by diippi; Feb 20th, 2008, 01:48 PM. Reason: Realised something !

              Comment


              • #8
                Are you sure that it's not being invoked? (perhaps the log level is higher than 'info' - you may see the log message if you lower the level).

                Note that message.acknowledge() is actually ignored for a transacted Session, and the current implementation of JmsMessageDrivenSourceAdapter is always setting 'transacted' to TRUE.

                -Mark

                Comment


                • #9
                  message.acknowledge

                  I am using the messageConverter to mainly set the acknowledge on the message so that it drains from the queue...Do yuo mean to say yuo are already doing it ?
                  If I listen to a queue using jms-source , it reads the message but does not removes it from the queue..what needs to be done here ?

                  Comment


                  • #10
                    When a JMS Session is 'transacted', then calls to message.acknowledge() have no effect. Instead, the JMS Message will only be removed from the queue once the Session commits. In the case of the JmsMessageDrivenSourceAdapter, the Session is always transacted and therefore should be committing only after successfully converting and sending a Spring Integration Message to a MessageChannel. Do you know if you are successfully sending to the MessageChannel?

                    -Mark

                    Comment


                    • #11
                      hey Mark..Sorry for my ignorance about the transacted session there..I understand now that it will commit only after a send..
                      The use case that I have though doesnt expects me to send a response immediately..this is sort of asynchronous receive and an asynchronous send that I will be doing later <triggered seperately> .
                      Is there a way that I can commit this transaction w/o sending something back on the channel ?

                      Comment


                      • #12
                        Sorry, I'm not talking about replying to a JMS queue - rather I was referring to the sending of a Spring Integration Message object to a Spring Integration MessageChannel. As soon as a JMS Message is received by the JmsMessageDrivenSourceAdapter it does automatically convert and send to a Spring Integration MessageChannel. Based on the configuration that you posted earlier, it would be "MyRequestChannel" in your case. The JMS Session should be committed as soon as the message is sent to that channel. Does that make sense?

                        -Mark

                        Comment


                        • #13
                          should work fine..but isnt..

                          If that is the case then its flowing to my channel quite alrite ..why is it not being removed from the queue then..

                          I have an endpoint registered on that channel and the handler does receives the message alrite ..
                          Code:
                          <endpoint input-channel="RequestChannel"
                          			  handler-ref="messageListener"
                          	          handler-method="onMessage"/>

                          Comment


                          • #14
                            I've just run through some local tests with a debugger, and I see the JMS Message being removed from the queue as soon as session.commit() is invoked after the sending method returns. Can you provide some information about your environment and/or how you are determining that the JMS Messages are not being removed from the queue? Also do you know which release of Spring Integration you are using (either the Milestone-1 release or else a SVN r#) ?

                            Thanks,
                            -Mark

                            Comment


                            • #15
                              My environment

                              Im listening on a regular MQ queue using <jms-source> . The channel and adjoining handler recieves the message correctly. The MQ Browser still shows me the message on the queue and I receive it again on the next run..

                              Instead if I use jms-listener , I see that the queue is being drained..

                              I find this very strange too, wondering what might be causing this..

                              Im using the SVN release 1.0.0.m2.20080218 at the moment, but was facing the same issue with 1.0.0.m1 too.
                              Which is the class that actually does session.commit() ?
                              Maybe I can debug this thing to better understand the flow..

                              Appreciate your help and patience with this issue !

                              Comment

                              Working...
                              X