3

Im very new to Spring and JMS. Ive been trying to come up with an implementation that involves activemq and Spring as follows.

spring-context.xml
<bean id="sampleApacheConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" lazy-init="true">
    <property name="brokerURL" value="tcp://localhost:61616"/>
    <property name="userName" value=“kodeseeker"/>
    <property name="password" value=“mypassword"/>

</bean>

 <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <constructor-arg ref="sampleApacheConnectionFactory" />
    </bean>

    <!--  Default Destination Queue Definition-->
    <bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg index="0" value="test.Foo"/>
    </bean>

    <!-- JmsTemplate Definition -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="defaultDestination" ref="defaultDestination" />
    </bean>

    <!-- Message Sender Definition -->
    <bean id="messageSender" class="com.mypackage.Publisher2">
    </bean>

<!-- Message Receiver Definition -->
    <bean id="messageReceiver" class="com.mypackage.Listener">

    </bean>
       <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destinationName" value="test.Foo" />
        <property name="messageListener" ref="messageReceiver" />
    </bean>

</beans>

Publisher2.java

public class Publisher2 {

 @Autowired
 protected JmsTemplate jmsTemplate;
 .......
// function called to perform update.
  public void publishUpdate(final CustomMessage payload) throws JMSException {
      LOGGER.entry();
      try {
          JmsTemplate jmsTemp= this.jmsTemplate;
          if(jmsTemp ==null){
        //jmsTemplate is ALWAYS null.
           LOGGER.error("Jms Template is never initialized!!");
           return;
          }
          jmsTemp.send(new MessageCreator(){
         @Override
         public Message createMessage(Session session) throws JMSException {
             Message message = message(payload,session);    
             LOGGER.info("Sending message");
             return message;
        }
        });
      } catch (Exception jmsExcpetion) {
          LOGGER.error("Error placing message on Queue",jmsExcpetion);
     
      }
      LOGGER.exit();
  }
}

Is there anything I specifically need to do in order to initialize jmsTemplate? Id be happy to provide any more details if necessary .

Edit 1: Class calling the publishupdate

public class UpdateHandlerImpl implements UpdateHandler {
    private final Publisher2 publisher;
    ....
    public UpdateHandlerImpl() {
        this(new Publisher2());
    }
    public UpdateHandlerImpl(
            final Publisher2 publisher) {
           this. publisher = publisher;
    }
    ....
    @Override
    public void  handle(final CustomMessage entity) {
        try {
                     publisher. publishUpdate(entity);
        } catch (final JMSException e) {
            LOGGER.error("Error sending message", e);
        }

            }
   …..
    }

Edit 3: Updated version of UpdateHandlerImpl based on @keith's input

public class UpdateHandlerImpl implements UpdateHandler {
    //Hoping spring wires this?
    Publisher2 publisher;
    @Override
    public void  handle(final CustomMessage entity) {
        try {
                     publisher. publishUpdate(entity);
        } catch (final JMSException e) {
            LOGGER.error("Error sending message", e);
        }

            }
   …..
    }

Edit 2: The spring context is loaded through mule( this is a mule application) on startup using the following annotation.

<spring:beans>
        <spring:import resource="classpath:spring-context.xml" />
    </spring:beans>
NewbUser
  • 303
  • 2
  • 12

1 Answers1

1

If you are creating Publisher2 using new, you will not have the dependencies wired on the instance you create. Instead, define it as a Spring bean in your context file and get it from there.

Edit

It's as I suspected, in your latest update to the question you confirmed that you are creating a Publisher2 with new.

public UpdateHandlerImpl() {
        this(new Publisher2());
    }

This is not how Spring works. See Section 6.3.2 of the Spring Framework documentation on instantiating beans. (In short, create the bean using the context)

Keith
  • 3,079
  • 2
  • 17
  • 26
  • Thanks for answering .. But am I not doing that already in the spring-context file ` ` based on the link you provided. – NewbUser Oct 20 '15 at 03:08
  • You shouldn't be instantiating _any_ objects in your code that you expect Spring to wire for you. In this case, the `new Publisher2())` is defeating your use of dependency injection since that is not a bean managed by the framework. – Keith Oct 20 '15 at 03:10
  • I added the following line to the `spring-context.xml`. ` ` and removed instantiation. ie. made the new class like [this](http://codeshare.io/adewd). But jmsTemplate continues to be null. What am i missing? – NewbUser Oct 20 '15 at 03:35
  • 1
    Spring doesn't work with "hope". You have to tell Spring to inject the dependencies in the class, either with the Autowired annotation on the field and Component on the class (to make it a Spring bean) or with a bean definition in the XML (you also have to define UpdateHandlerImpl as Spring bean). – dunni Oct 20 '15 at 05:03
  • Hope.... Too funny, but disappointed to hear it. – Nicholas Oct 20 '15 at 12:18