MDBとJCAのおはなし
JBoss Advent Calendar 2011の13日目のエントリです。
MDBはメッセージドリブンビーンの略であり、メッセージを処理するEJBコンポーネントです。MDBはJMSのメッセージを処理するコンポーネント、という古い認識の人もたまに居るのですが、MDBはかなり前からJMSに限定しない技術となっています。
最初にMDBが策定されたのはJ2EE 1.3に含まれていたEJB 2.0仕様で、この時点ではMDBはJMSのメッセージを処理するもの、と規程されていました。J2EE 1.4の時代となり、EJB2.1の策定に伴いMDBの動作の仕様の中心はJCA仕様(Java EE Connector Architecture)に移り、メッセージはJMSのものに限定せず、ありとあらゆるメッセージ受信処理ができるよう一段階上の抽象化がなされました。
JCAはJava EEと外部システムをつなぐインテグレーションのためのテクノロジです。MDBはこのうちMessage inflowという部分がメインで、JBoss ASではJMS、Mail、QuartzなどのMDBをサポートしていました。また、ファイルを入力メッセージとするJCA Message inflowのサンプルも提供しています。
現在のJBoss AS 7ではビルトインではJMSのみのサポートとなっていますが、他のものも追って提供されていくことと思います。Mail用のものなどはJBoss AS 7に含まれるJCA実装であるIronJacamarのリポジトリ上には既に存在しています。
また、僕もだいぶ前ですがJBoss AS 7上で動作するTwitter向けのJCA 1.6 Message inflowリソースアダプタを書いてみました。TwitterのクエリAPIを利用し、マッチするツイートをMDBに渡します。以下の例では"jboss"を含むツイートを起動中ずっと標準出力にべろべろと吐き出します。
import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import org.jboss.ejb3.annotation.ResourceAdapter; import jp.programmers.resource.adapter.twitter.inflow.TweetListener; import twitter4j.Tweet; @MessageDriven(activationConfig={ @ActivationConfigProperty(propertyName="query", propertyValue="jboss") }) @ResourceAdapter("twitter-ra") public class TwitterMDB implements TweetListener { public void onTweet(Tweet t) { System.out.println(t); } }
JCAはWikipediaのJava EE Connector Architectureのページに簡潔にまとまっていますが、他にもConnection managementやTransaction managementなど多くの機能を提供します。例えばJDBCは通常データベースとのベーシックな接続機能やJDBC独自(データベース独自)のトランザクションシステムを提供しますが、JDBC向けJCAアダプタでは接続プールやJTAトランザクションとの連携というような機能をJDBCに付加します。JDBC向けJCAアダプタ、というのはつまるところJBoss ASのJDBCデータソースを提供している部分です。これはJMSでも同じで、JMS用JCAリソースアダプタは同じくJMSにコネクションプールを提供し、JCAトランザクションをJMSトランザクションにブリッジする機能を付与します。JCAはあまりJava EEのアプリケーション開発者から直接見えない部分ですが、アプリケーションサーバの基礎とも言える非常に重要な機能を提供しているのです。
MDBのプログラミングモデルはシンプルで扱いやすく、例えばモダンなところだとScalaなどで採用されているActorモデルなどにも似ています。リソースアダプタ実装がメッセージを振り分け、MDBで個々のメッセージを処理します。スレッドの割り当てなどはコンテナ側で設定できる、という仕組みです。