Over a million developers have joined DZone.

Basic MDB with Scala, Sbt and JEE 6

· Java Zone

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.

While I am an Akka fan, and a Typesafe follower, in this post I will continue presenting scala on the JEE 6 environment and introduce basic message driven beans (MDB ) using scala language.

As an example let’s take a simple MDB that will consome operation commands like add and substract and my be asked to replay by the result

I- Exchange API


sealed trait TOperation
case class Add(x:Int) extends  TOperation
case class Sub(x:Int) extends TOperation
case class Sum extends TOperation
case class Count(x:Int) extends TOperation

II- The listener

The object

object MDbListener {
  var count = 0
  val L = Logger.getLogger(classOf[MDbListener])
}

 

The class
 
@MessageDriven(
  messageListenerInterface=classOf[MessageListener],
  mappedName = "jms/toMdb",
  activationConfig = Array(
    new ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    new ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")))
class MDbListener extends MessageListener {

  import MDbListener._

  override def onMessage(message: Message) {
    L.debug("Message Received")

    message match {
      case o: ObjectMessage => {
          try {
            val obj = o.getObject()
            obj match {
              case action: TOperation => handle(action)
              case _ => L.warn("Unkownen msg")
            }
          } catch {
            case ex: Exception => L.error(">>> Exception", ex)
          }

        }
      case _ => L.warn("unknown msg")
    }
  }

  def handle(op: TOperation ) = op match {/* TODO */
  }
}
 

Nothing special here but be careful to not forget adding messageListenerInterface=classOf[MessageListener] on MessageDriven annotation.  This is because of ScalaObject super class and that’s all for the listener.

III- The sender

The handle method will do mathematical operations and can be requested to send the sum to another JMS Queue.

def handle(op: TOperation ) = op match {
    case   Add(x) => count +=x
    case   Sub(x) => count -=x
    case   s:Sum =>  sendJMSMessageToTt( Count (count))
    case   c:Count => L.warn ("Wrong message destination!")
  }

Very easy with pattern matching!

The sendJmsMessageToIt method can be done like the following

 

 @Resource(mappedName = "jms/Rep")
  var  queue :Queue=_
  @Resource(mappedName = "jms/RepFactory")
  var  factory:ConnectionFactory=_

  private [ws ] def sendJMSMessageToTt( messageData:Count)  {
    def  createJMSMessageForjmsTt( session:Session,  messageData:Count):Message={
      val om = session.createObjectMessage()
      om.setObject(messageData)
      om
    }

    def tryWith[A<%{ def close()}](ac :A)(f: A=> Unit)
    {
      try {f} finally { ac.close }
    }

    tryWith(factory.createConnection()){
      connection => tryWith(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
        	session =>  tryWith( session createProducer queue ){
          		messageProducer => messageProducer.send(createJMSMessageForjmsTt(session, messageData))
        }
      }
    }
  }

Here we used an old trick to manage resources : http://ouertani.com/2010/12/scala-try-with-resources/

The Java Zone is brought to you in partnership with JetBrains.  Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience.

Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}