Announcement Announcement Module
Collapse
No announcement yet.
Just a quick one Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Just a quick one

    Judging by the solution to my previous (very first) post - I can only expect that I am again doing something fundamentally wrong here.

    I am attempting to do a synchronous JMS call and everything works fine if sender and receiver are deployed in the same JVM (kind of pointless but bear with me), if I split them into two separate 'test stubs' each with its own main the sender times out, even though it creates temporary queue etc. The receiver receives the message and sends it back yet the sync sender times out .

    Looked in the log file (I am using Active MQ) found lines confirming that temp queue gets created etc.. yet it times out. As I said if deployed within the same context (as components adn not CLI apps this time) it works fine(?!)

    I am really at a loss here and would appreciate if anyone could offer any insights.

    Regards,

    M.

    key code included:

    // Client

    Code:
    public static void main(String[] args) {
    ApplicationContext mainContext = new ClassPathXmlApplicationContext(
    				CONFIG_LOCATIONS);
    JmsTestClient jmsTestClient = mainContext.getBean("jmsTestClient", JmsTestClient.class);
    		
    		jmsTestClient.runTest();
    }
    
    private void runTest() {
    testType = jmsTestSyncSender.send("sendResponse");
    		
    		System.out.println("Received: " + ((testType != null) ? testType.getName() : "NULL"));
    	}
    
    // SyncSender send method
    
    public TestType send(final String str) {
    
    		TestType testType = null;
    
    		try {
    
    			testType = (TestType) jmsTemplate.execute(new SessionCallback<TestType>() {
    
    						public TestType doInJms(Session session)
    								throws JMSException {
    							MessageProducer producer = session
    									.createProducer(destination);
    							TemporaryQueue tempQueue = session
    									.createTemporaryQueue();
    							TextMessage message = session
    									.createTextMessage(str);
    
    							message.setJMSReplyTo(tempQueue);
    							message.setJMSCorrelationID(String.valueOf(System
    									.nanoTime()));
    							producer.send(message);
    
    							MessageConsumer consumer = session
    									.createConsumer(tempQueue);
    
    							Message response = consumer.receive(10000);
    
    							JmsUtils.closeMessageProducer(producer);
    							JmsUtils.closeMessageConsumer(consumer);
    
    							TestType returnedType = null;
    
    							if (response != null
    									&& response instanceof ActiveMQObjectMessage) {
    
    								try {
    									ObjectInputStream in = new ObjectInputStream(
    											new ByteArrayInputStream(
    													((ActiveMQObjectMessage) response)
    															.getContent().data));
    									returnedType = (TestType) in.readObject();
    
    									System.out.println((returnedType != null) ? returnedType.getName() : "NULL");
    
    								} catch (IOException e) {
    
    									e.printStackTrace();
    								} catch (ClassNotFoundException cnfe) {
    									cnfe.printStackTrace();
    								}
    
    							} else {
    
    								if (response != null
    										&& !(response instanceof ActiveMQObjectMessage)) {
    									System.out.println("Unsupported response detected ["
    											+ response.toString()
    											+ "] "
    											+ " expected "
    											+ ActiveMQObjectMessage.class
    													.getName()
    											+ " returning null.");
    								} else {
    									System.out.println(String.valueOf(response)
    											+ " response received.");
    								}
    
    							}
    
    							return returnedType;
    						}
    
    					});
    
    		} catch (JmsException e) {
    			e.printStackTrace();
    		}
    
    		return testType;
    	}
    
    // SyncReceiver
    
    @Component
    public class JmsTestSyncReceiver {
    
    	public TestType receive(String str) {
    
    		TestType testType = null;
    		System.out.println("Received: " + str);
    		
    		if (str.equalsIgnoreCase("sendResponse")) {
    			testType = new TestType();
    			testType.setName("Mutombo!");
    		}
    		
    		return testType;
    	}
    }
    
    <!-- Receiver side setup -->
    
    <bean id="jmsTestSyncContainer"
    		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    		<property name="connectionFactory" ref="jmsFactory" />
    		<property name="destination" ref="testSyncDestination" />
    		<property name="messageListener" ref="testSyncMessageListener" />
    	</bean>
    
    	<bean id="testSyncDestination" class="org.apache.activemq.command.ActiveMQQueue">
    		<constructor-arg value="${TEST_TYPE_SYNC_QUEUE}" />
    	</bean>
    
    	<bean id="testSyncMessageListener"
    		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    		<constructor-arg>
    			<bean
    				class="jms.test.JmsTestSyncReceiver" />
    		</constructor-arg>
    		<property name="defaultListenerMethod" value="receive" />
    	</bean>
    
    // Sender side setup
    
    	<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
    		<constructor-arg value="${TEST_TYPE_SYNC_QUEUE}" />
    	</bean>
    	
    	<bean id="jmsTestSyncSender"
    		class="jms.test.client.JmsTestSyncSender">
    	</bean>
    	
    	<bean id="jmsTestClient"
    		class="jms.test.client.JmsTestClient" />
    Last edited by Gary Russell; Nov 5th, 2012, 06:37 AM.

  • #2
    Please use [ code][/code ] tags when posting code...

    Make sure you have a standalone JMS provider and that it operates over JVMs. So don't use a jvm based protocol but make sure it is a tcp based one.

    Comment


    • #3
      Anything else to double check that you can think of?

      I run my ActiveMQ as a standalone component (as in it has a 'black screen' of its own) I have just looked into my setup and my url settings for both receiver and sender seem to be correct (BROKER_URL=tcp://localhost:61616)

      Anything else to double check that you can think of?

      Regards, M.

      Originally posted by Marten Deinum View Post
      Please use [ code][/code ] tags when posting code...

      Make sure you have a standalone JMS provider and that it operates over JVMs. So don't use a jvm based protocol but make sure it is a tcp based one.

      Comment


      • #4
        There must be no spaces in the [ code ] [ /code ] tags - I edited your post.

        I suggest you turn on TRACE level logging on both sides.

        You also might want to consider using Spring Integration JMS Gateways; then, all this low level plumbing is taken care of for you...

        http://static.springsource.org/sprin.../html/jms.html

        Comment


        • #5
          It seems to me all you are trying to accomplish is a simple request/reply over JMS.
          There is obviously too much code for anyone to review, but If you still trying to fing code-only solution I am sure googling for a good sample would resolve your issue. However you don't even need to do that. I'd suggest to look at Spring Integration framework which abstracts all that boilerplate and allows you to configure a pair of Outbound/Inbound gateways.

          Here is the sample:
          https://github.com/SpringSource/spri...ster/basic/jms

          Comment


          • #6
            This sounds like the way to go.

            Thanks, M.

            Originally posted by Gary Russell View Post
            There must be no spaces in the [ code ] [ /code ] tags - I edited your post.

            I suggest you turn on TRACE level logging on both sides.

            You also might want to consider using Spring Integration JMS Gateways; then, all this low level plumbing is taken care of for you...

            http://static.springsource.org/sprin.../html/jms.html

            Comment


            • #7
              Solution (posted here for posterity only)

              As I suspected, turned out to be a classic RTFM case.

              I was using jmsTemplate.execute(SessionCallback<t> action) instead of jmsTemplate.execute(SessionCallback<t> action, boolean startConnection) which meant that it would work fine when deployed in a single JVM, however in a multiple JVM deployment, it requires that one 'connects' first.

              Hope this helps someone.

              Having said this - I still think that 'integration' is the way to go as it will probably do away with issues like this one.

              Originally posted by mushashi View Post
              This sounds like the way to go.

              Thanks, M.
              Last edited by mushashi; Nov 6th, 2012, 02:48 AM.

              Comment

              Working...
              X