0

I have a Java Swing GUI client that communicates with a WildFly server.

standalone-full.xml

<jms-queue name="goReceiveFmSvrQueue">
  <entry name="java:/jboss/exported/jms/goReceiveFmSvrQueue"/>
  <durable>true</durable>
</jms-queue>
<jms-queue name="goSendToSvrQueue">
  <entry name="java:jboss/exported/jms/goSendToSvrQueue"/>
  <durable>true</durable>
</jms-queue>

My client has a Runnable MsgCenterSend class. It instantiates MsgCenterSend. then calls msgCenter.run() to start a connection. Then used msgCenter.send() to send a message. And msgCenter.stop() to close it when the client closes.

Does that make sense?

Or Should the client just create a connection, session, destination and producer every time it needs to send message? And if it does that should it be done in a separate Thread?

public class MsgCenterSend implements Runnable {
  private Connection       connection             = null;
  private MessageProducer  msgProducer            = null;
  private Session          session                = null;

  public void run() {
      Context ctx = new InitialContext(/*connection propoerties*/);
      HornetQJMSConnectionFactory jmsConnectionFactory = (HornetQJMSConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
      this.connection = jmsConnectionFactory.createConnection("jmsuser", "jmsuser@123");
      this.session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      Destination sendToDestination = (Destination) ctx.lookup("jms/goSendToSvrQueue");
      this.msgProducer = this.session.createProducer(sendToDestination);
      this.connection.start();
  }

  public boolean sendMsg (/*parameters*/) { 
    ObjectMessage message = this.session.createObjectMessage();
    // set MessageObject and Properties
    this.msgProducer.send(message);
  }

  public void stop () 
      this.connection.stop();
    }
  }
}

The client uses stop() on exit.

For now my MessageBean looks like:

@MessageDriven(  
  activationConfig ={  
    @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),  
    @ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),  
    @ActivationConfigProperty(propertyName="destination", propertyValue="jms/goSendToSvrQueue")
  }) 
public class GoMsgBean implements MessageListener {
  @ApplicationScoped
  @Inject
  JMSContext jmsCtx;
  //This is queue client listens to.  Server sends replies to it.
  @Resource(name = "java:jboss/exported/jms/goReceiveFmSvrQueue")  
  private Queue svrSendQueue; 


  public GoMsgBean () {
  }

  @PostConstruct
  public void myInit () {
    System.out.println("XXXXXXXXXX Post Construct - GoMsgBean XXXXXXXXXX");
  }
  @PreDestroy
  public void myDestroy () {
    System.out.println("XXXXXXXXXX Post Destroy - logger XXXXXXXXXX");
  }

  public void onMessage(Message msg) {
    System.out.println("XXXXXXXXXX MessageBean received a Message XXXXXXXXX");
  }
}
George
  • 509
  • 2
  • 9
  • 25

2 Answers2

1

Even infrequent I don't see a problem keeping the connection open, unless you have serious resource constraints, messaging protocols are usually light-weight enough to just keep open and not worry about connect/disconnect/reconnect. ActiveMQ's documentation says exactly that, and though I can't find the per-connection memory overhead it's not a lot. There's also server-side configuration that can help manage large volumes of messages, but again, I'm not worried about it.

One disadvantage of ActiveMQ is that it doesn't support true clustering, so if you're really dealing with 10's or 100's of thousands of connections, then you're going to have problems.

And in the end, you'll need to do performance analysis on your end to make sure the application behaves with the server.

Scott Sosna
  • 1,443
  • 1
  • 8
  • 8
0

If your application is sending messages frequently to the same destination then it is a best practice to create connection, session and producer once and re-use them because creating connection, session etc are costly operations.

If messages are not sent frequently, then it's better to create all the required objects, send message and close the objects. This way resources are freed up on the messaging provider.

Shashi
  • 14,980
  • 2
  • 33
  • 52
  • Thank you for your help. (sorry for the delyed acknowledgement but I can't seem to convince this web site I want to follow my question). But that still leaves unanswered the question about use of a separate thread. The client will have frequent messages while open. So creating and keeping Connection, etc. objects makes sense. But do I leave the Connection running? Or stop and start it? I hope that makes sense, because I'm just starting on JMS. – George Feb 18 '16 at 01:04
  • Use of a separate thread to send/receive messages up to your design. But note that Session, Producer and Consumer objects are not thread safe. Hence all these objects must be used in the same thread in which they were created. HTH – Shashi Feb 18 '16 at 06:46
  • Thanks Sashi. That will save me a lot of future grief I think. – George Feb 26 '16 at 19:07