復習日記

勤務時間内で理解できなかったことやつまづいたことをまとめていく予定。

JMS 2.0 and EJB 3.2 Message-Driven Bean in WildFly 8

今回は、タイトルの通り、JMSのお勉強。

仕事でJMSを使うことになった理由は、他シス連携する際、大量のアクセスをさばくためって感じです。

同期処理で他シス連携してたら、対抗側をパンクさせちゃうかもしれないから、JMSで非同期処理させるんですね~。

さて、とりあえず、動くsampleを落としてくる。

quickstart/helloworld-mdb at master · wildfly/quickstart · GitHub

READMEを見る

このプロジェクトをビルドしてできたwarをwildflyにデプロイすると JMSのdestinationが自動で作成されて、キューの送信、受信ができるらしい。

環境

実行方法

1.fullプロファイルでwildflyを起動

%JBOSS_HOME%\bin\standalone.bat -c standalone-full.xml

2.maven実行

cd %ワークスペース%\quickstart-master\helloworld-mdb
mvn clean package wildfly:deploy

3.ログ(%JBOSS_HOME%\standalone\log\server.log)を確認

2014-11-21 22:37:37,053 INFO  [org.jboss.as.messaging] (MSC service thread 1-16) JBAS011601: Bound messaging object to jndi name java:/queue/HELLOWORLDMDBQueue
2014-11-21 22:37:37,053 INFO  [org.jboss.as.messaging] (MSC service thread 1-9) JBAS011601: Bound messaging object to jndi name java:/topic/HELLOWORLDMDBTopic
2014-11-21 22:37:37,070 INFO  [org.jboss.weld.deployer] (MSC service thread 1-10) JBAS016005: Starting Services for CDI deployment: wildfly-helloworld-mdb.war
2014-11-21 22:37:37,105 INFO  [org.jboss.weld.Version] (MSC service thread 1-10) WELD-000900: 2.1.2 (Final)
2014-11-21 22:37:37,128 INFO  [org.jboss.weld.deployer] (MSC service thread 1-14) JBAS016008: Starting weld service for deployment wildfly-helloworld-mdb.war
2014-11-21 22:37:37,128 INFO  [org.hornetq.core.server] (ServerService Thread Pool -- 60) HQ221003: trying to deploy queue jms.queue.HelloWorldMDBQueue
2014-11-21 22:37:37,286 INFO  [org.hornetq.core.server] (ServerService Thread Pool -- 61) HQ221003: trying to deploy queue jms.topic.HelloWorldMDBTopic
2014-11-21 22:37:37,428 INFO  [org.jboss.as.ejb3] (MSC service thread 1-10) JBAS014142: Started message driven bean 'HelloWorldQTopicMDB' with 'hornetq-ra.rar' resource adapter
2014-11-21 22:37:37,428 INFO  [org.jboss.as.ejb3] (MSC service thread 1-7) JBAS014142: Started message driven bean 'HelloWorldQueueMDB' with 'hornetq-ra.rar' resource adapter
2014-11-21 22:37:37,936 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-1) JBAS017534: Registered web context: /wildfly-helloworld-mdb
2014-11-21 22:37:38,116 INFO  [org.jboss.as.server] (management-handler-thread - 1) JBAS018559: Deployed "wildfly-helloworld-mdb.war" (runtime-name : "wildfly-helloworld-mdb.war")

うん。うまくいっている。

4.サーブレットにアクセスして送信の動作確認。

http://localhost:8080/wildfly-helloworld-mdb/

f:id:raimus0904:20141121225509j:plain

WildflyはJMSの実装にHornetQをつかっていて、そこのHelloWorldMDBQueueというキューにメッセージを送りましたよ、という画面。

5.キュー送信側(サーブレット

package org.jboss.as.quickstarts.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.jms.Destination;
import javax.jms.JMSContext;
import javax.jms.JMSDestinationDefinition;
import javax.jms.JMSDestinationDefinitions;
import javax.jms.Queue;
import javax.jms.Topic;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@JMSDestinationDefinitions(
        value =  {
                @JMSDestinationDefinition(
                        name = "java:/queue/HELLOWORLDMDBQueue",
                        interfaceName = "javax.jms.Queue",
                        destinationName = "HelloWorldMDBQueue"
                ),
                @JMSDestinationDefinition(
                        name = "java:/topic/HELLOWORLDMDBTopic",
                        interfaceName = "javax.jms.Topic",
                        destinationName = "HelloWorldMDBTopic"
                )
        }
)

@WebServlet("/HelloWorldMDBServletClient")
public class HelloWorldMDBServletClient extends HttpServlet {

    private static final long serialVersionUID = -8314035702649252239L;

    private static final int MSG_COUNT = 5;

    @Inject
    private JMSContext context;

    @Resource(lookup = "java:/queue/HELLOWORLDMDBQueue")
    private Queue queue;

    @Resource(lookup = "java:/topic/HELLOWORLDMDBTopic")
    private Topic topic;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.write("<h1>Quickstart: Example demonstrates the use of <strong>JMS 2.0</strong> and <strong>EJB 3.2 Message-Driven Bean</strong> in WildFly 8.</h1>");
        try {
            boolean useTopic = req.getParameterMap().keySet().contains("topic");
            final Destination destination = useTopic ? topic : queue;

            out.write("<p>Sending messages to <em>" + destination + "</em></p>");
            out.write("<h2>Following messages will be send to the destination:</h2>");
            for (int i = 0; i < MSG_COUNT; i++) {
                String text = "This is message " + (i + 1);
                context.createProducer().send(destination, text);
                out.write("Message (" + i + "): " + text + "</br>");
            }
            out.write("<p><i>Go to your WildFly Server console or Server log to see the result of messages processing</i></p>");
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}

6.キュー取り出し側(MDB)

package org.jboss.as.quickstarts.mdb;

import java.util.logging.Logger;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(name = "HelloWorldQueueMDB", activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/HELLOWORLDMDBQueue"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class HelloWorldQueueMDB implements MessageListener {

    private final static Logger LOGGER = Logger.getLogger(HelloWorldQueueMDB.class.toString());

    public void onMessage(Message rcvMessage) {
        TextMessage msg = null;
        try {
            if (rcvMessage instanceof TextMessage) {
                msg = (TextMessage) rcvMessage;
                LOGGER.info("Received Message from queue: " + msg.getText());
            } else {
                LOGGER.warning("Message of wrong type: " + rcvMessage.getClass().getName());
            }
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}

7.メッセージ受信ログ MDBはonMessageで受信したメッセージをログに吐いてます。

2014-11-21 22:49:27,729 INFO  [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-8 (HornetQ-client-global-threads-1549348)) Received Message from queue: This is message 1
2014-11-21 22:49:27,729 INFO  [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-9 (HornetQ-client-global-threads-1549348)) Received Message from queue: This is message 2
2014-11-21 22:49:27,729 INFO  [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-12 (HornetQ-client-global-threads-1549348)) Received Message from queue: This is message 3
2014-11-21 22:49:27,738 INFO  [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-11 (HornetQ-client-global-threads-1549348)) Received Message from queue: This is message 4
2014-11-21 22:49:27,772 INFO  [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-11 (HornetQ-client-global-threads-1549348)) Received Message from queue: This is message 5

次回はActiveMQ使ってみます。