目次

背景

EJBの中の処理を並列化したいので、何か使えるネタが無いかなと探してみた。

J2EE1.4という条件付けだと、

  • MDB
  • JCAのWork Management機能
  • (Container限定なら)commonj
選択肢説明
Message Driven Bean(MDB)Queueを間に挟んで、msgからMDBをinvokeするのはcontainerの仕事で、msg毎に必要があればthreadを生成して、処理を並列化できる
Java Connector Architecture(JCA)JCAの仕様に、ResourceAdapter?に求められる機能として、Work Managment機能がある。このための javax.resouce.spi.work.Work interfaceは爽やかに Runnableを継承してるので、うまく使えるかも。
commonjjavax.resouce.spi.workパッケージに類似のWeb層(JSP/Servlet)、EJB層で使えるF/W。JSR237としてJCPに提案されている仕様のref実装として、WebSphere?、WebLogic?には実装されている模様。

と3択になった。

terminology

面倒なので、英文字省略ものはここに。よく使われてるものから、このぺーじ編集のためだけに 何度も出てくるから・・ってんで書いてるのもあります。
省略形もと蛇足
EJBEnterprise JavaBeans?beanと言うときとbeansというときの違いがようわからんが・・複数は抽象、単数は直指定なのかな。
MDBMessage Driven Bean
JCAJava Connector Architecture
RAResource Adapter
ASApplication Serverネットワークだと、自律・・
J2EEJava 2 Platform Enterprise EditionいまはJava EE5だな。
EISEnterprise Information SystemASの外にあるなんか。RDBMSとかM/Fとかその他諸々。JAC1.5仕様書中ではresource managerと同義とされる場合もある。
EAIEnterprise Application Integration何って・・さぁ?w
CCICommon Client InterfaceRAがクライアント(=Servlet/EJB)に提供する標準I/F。Common Gateway Interfaceと読み間違えたりしる。;-)

各選択肢のいいところ・わるいところ

選択肢その1 MDB

  • いいところ
    • (new Thread()).start()みたいな部分を、jmsの作法に合わせた後、最後に QueueSender?.send(msg)とやるだけなので実装が簡単
    • J2EE1.4での非同期処理をしたい場合の標準的な方法
    • Googleで探すとサンプルはいっぱいあるし、J2EE1.4 samplesにもすぐ使えるものがある
  • わるいところ
    • 何も知らないと、Thread/Runnableとの関連は見えないので、使ったことがない人にはなにやら難しそうに感じる
    • 実装以外に運用(=Queueの設置・設定)が必須

選択肢その2 JCAの場合

  • いいところ
    • Runnableを継承したinterfaceを使えるので、Threadで実装してれば、Runnableを実装した部分はそのまま流用できそう。
  • わるいところ
    • RA(Resource Adapter)を作る必要があるので、EJBからの呼び出し方をJCAの作法に合わせる必要がある。
    • 仕様書にもある通り、普通のWeb/EJB開発者の担当領域では無い

選択肢その3 commonjの場合

  • いいところ
    • JCAから欲しいところだけ抜いてある
  • わるいところ
    • J2EE Containerが限定される
    • InProgress?のstatusが2003年以降見えない。標準仕様としてFinal Releaseが出るのが遠そう(ってか出ない気がw)
    • 大人の事情ってやつで、WebSphere?/WebLogic?は・・ ;-)

作りたいものの雰囲気は

こんな感じです。
       [ejb]
         |
      +--+--+--- 並列化するしくみ
      |  |  |
 Threadみたいな感じ?

EJBとThread

JCAはRA(Resouce Adapter)を作る場合の仕様であり、この中のWM(Work Managment)とLM(Lifecycle Managment)に対応する pkg javax.recouce.spi.workが、J2EE1.4 APIの中でThreadを利用することを前提としている。
なお、J2EE1.4の仕様に含まれるEJB2.1においては、enterprise beanはThreadのi/f各種(start,stop,suspend, resumeとか 優先度、名前の変更)、ThreadGroup?の操作してはならない(must not)と記載されている。
 Enterprise JavaBeans? 2.1, Final Release 
   Chapter 25 Runtime Environement
   25.1.2 Programing Restrictions (page 563)より抜粋

    ・The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt
      to start, stop, suspend or resume a thread, or to change a thread's priority or name. The enter-
      prise bean must not attempt to manage thread group.
	
    Thease functions are reserve for the EJB container. Allowing the enterprise bean to manage threads
    would decrease to conainter's ability to properly manage the runtime environment.

そういうことなので、上記の「Threadみたいな感じ」のところをホントに Threadでやっちゃった場合、EJBコンテナにおけるデータ不整合に起因する Exceptionや異常動作があっても知ったこっちゃ無いということになります・・よ?

実装とか

選択肢その1 MDB

J2EE 1.4 Samples Bundleのejb/mdbにあるSimpleMessageBean?.javaが、上図のThreadみたいな感じのところになり、 並列化する仕組みはJMS(=Message Queue)です。

選択肢その2 JCAの場合

後述w

選択肢その3 commonjの場合

まぁ、この辺でも ;-)

Resource Adapterをつくろう(for 選択肢その2)

ということで、仕方ないwので、RA(Resource Adapter)を作ってみる。
読めば読むほど、並列化のためにRAなんてあり得ないと思えてくるが、まぁ、気にしない。;-)

RAって?

RAはASにpluginできるシステムレベルのs/w driverで、(AS上の)Java applicationによって、 EISに接続する際に使われる。こんな感じかな。
くくり何があるか作る人対応する仕様書(J2EE1.4の場合)
アプリケーションJSP、EJB、Servletアプリ開発者Servlet2.4、JSP1.2、EJB2.1
ContainerWebコンテナ、EJBコンテナメーカと有志の人?J2EE1.4 specとかその他もろもろ(JTA/JTSとかもここに押し込みw)
RAJMSRAとかJDBCRAは普通ある。他いろいろで、このページの対象EISベンダJCA1.5
EISRDBMS、SMTP鯖、メインフレーム、その他いろいろいろいろなんだろね。

EISとの連携の仕方によって、RAは2種類に分類される。

  • outbound
    • ASからEISに働きかける場合の仲介役。アプリケーション契機でEISへのアクセスが発生する。全ての処理はアプリケーションThreadのcontextで行われる。
  • inbound
    • EISからASに働きかける場合の仲介役。EIS契機でアプリケーション(EJB)へのアクセスが発生する。処理は、RAはASから与えられたthread、または自身のthreadで行われる。
  • bi-direction
    • in/outの両方に対応する場合。

JCA1.0に対するJCA1.5の拡張

JCA1.0ではEISとの接続を実現する上で、CM(connection managment),TM(transaction management)の管理とsecurity、 CCI、deployとpkg構成に関してが記されている。
JCA1.5ではこれに加えて、
  • Lifecycle management(LM)
    • ASがRAのライフサイクル(起動、停止、再配備とか)を管理するための仕様。
  • Work management(WM)
    • RAにAS管理のThreadを使うことが出来るようにする仕様。
  • Transaction Inflow(TI)
    • EISからのTransactionをRAで受け付けることが出来るようにするための仕様。
  • Message Inflow(MI)
    • AS外部から受け付けるメッセージをRAで受け付けることが出来るようにするための仕様。併せてJMSやJAXMのような様々なmessage providerを組み込む場合の仕様ともなっている。
  • RA3種類(実質2種類)のpkgの違いを記載

が入っている。JCA1.0の仕様書が188ページなのに対して、JCA1.5は490ページとだいぶ増えてる。

RAに求められる機能

SPECにはRA、ASのそれぞれに求める要求が記載されているが、ここはRAのためだけなので、 RAに求められる機能を作る上で必要な範囲でまとめてみる。今回はoutbound RAで、且つ WMを使いたい。まず、JCA1.5の仕様書にあるoutbound RAの実装する機能一覧はこんな感じ。

JCA1.5 16.2節 TABLE16-1 Resource Adapter API Requirements より抜粋

種別LMWMMITICMTMSMCCI
Outbound??+++?
Inbound+?+?
両方(↑2段の&)+?+?+++?

記号意味
+必須
?あってもなくてもどちらでもいい
無印いらない

ということなので、outboound RAで、実装範囲はLM,WM,CM,TM,SMにすることが確定。
CCIは気が向けば・・かな。

前置き

各機能の前提になる項目をまとめとく。JCA1.5SPECから抜いているのはResourceAdapter?の実装者向け 情報に限定している。

JavaBean?

RAが実装すべきinterfaceの実装クラスの要件として、JavaBean?であることと言う記載がある。
これは JavaBeans?の仕様書(1.01 Final Release on page F-2)を見ろと JCA1.5仕様書 16.3 JavaBean? Requirements節に書いてある。
要は普通のJavaBean?にしろということで、下記2条件を満たす必要がある。
  • null constructorをもつ(must)
  • JavaBean? instanceのpublic propertyにはsetter/getterを用意する(must)

また J2SE1.4からは marker interfaceとして java.io.Serializableをimplementsする必要は無くなっている。

Lifecycle managment

実装する上での注意点は下記の通り。

ResouceAdapter?実装クラスのメソッドとか(5.3.1節に対応)

  • 実装クラスはJavaBean?にする
  • java.lang.Object.equals() を実装する
    • ASは同じResourceAdapter?を1JVM上で複数同時に起動することを許されている。
    • このため、equalsメソッドでRAインスタンスの同一性を判断できなくてはいけない。
  • 関連する参照は一式ResouceAdapter?にもってた方がいいだろう。(特に停止のため)
  • RA動作中はManagedConnectionFactory?(CM機能)やActivationSpec?(IM機能)インスタンス、その他たくさんのinstanceを保持するだろう。

ManagedConnectionFactory?(5.3.2節に対応)

ManagedConnectionFactory?はResourceAdapter?とResourceAdapterAssociation?インターフェースを通じて、 関連性を持つ。特にResourceAdapter?のsetter(setResourceAdapter())はManagedConnectionFactory?インスタンスの ライフサイクル中で1度以上呼ばれてはならない。

ActivationSpec?(5.3.3節に対応)

省略。IMやらないし。

ResrouceAdapter?の停止

RAの停止は
  • appサーバが停止するとき
  • RAがundeployされるとき

の2パターンがある。停止は2phaseに分かれていて、phase1はResourceAdapter?.stop() をASが呼ぶ前に責任もって、RAと独立に使われているリソースの停止処理をしれというところ。 つまり、RA実装者には関係ない。ph2はstop()が呼ばれるところなので、 ResouceAdapter?.stop()の実装で何をする必要があるかになる。
細かくは書いていないが、色々正常に終わる前提の同期処理で書いちゃっていい(=stop()が 最悪ブロックしてもいいってまでは書いてないが・・)とある。関連リソースの全てを実装することに なるので、Work.release()とかちゃんと終わるようにしておけということだろう。
stop()処理中でcatchしてない例外があった場合、上に投げたらASはログは取るとのこと。

Work managment

Connection management

Transaction management

Security management


Last-modified: 2006-06-14 20:48:58