JBoss EAP 6.2のリモートEJB呼び出し
JBoss / WildFly (全部俺) Advent Calendar 2013の9日目です。
まず最初に注意です。リモートEJB呼び出しとか基本的には過去の遺産なので、できる限りサービスの呼び出しはRESTにしましょう。ポータブルでシンプルなAPIのほうが良い。
さて、JBoss EAP 6のリモートEJBの呼び出し方法がEAP 5までとは異なるので、ちょっと遊んでみます。JBoss EAP 6.2.0を使います。
JBoss EAP 5まではJNDIからルックアップして呼び出すだけだったのですが、このモデルではEJB呼び出しのリソース境界となるAPIがありません。そのため、EJBクライアントがソケットやスレッドをプールできない、プールしたとしてもいつクローズしていいか分からないという暗黙のプール実装を行うしかないというオチになっていました。EJBクライアント側でEJBの呼び出しコンテキストがきちんと管理できれば、より効率的なEJB呼び出しが可能になります。というのを実装したのがJBoss EAP 6のEJB呼び出しモデルです。
JBoss EAP 6.0ではEJBクライアントコンテキスト管理にJBossのAPIを利用する必要があったのですが、JBoss EAP 6.1からはJNDIのAPIからEJBクライアントコンテキストの管理ができ、JBossのAPIを利用する必要はなくなっています。
サーバサイドはas7-ejbというAS7向けのEJBサンプル実装を前に作ったのでそれをそのまま使います。このプロジェクトはAS7向けにクライアントも実行できるそこそこきちんとしたpom.xmlを書いたのですが、EAP6に対応させるのがかなり面倒そうだったのでやっぱり手抜きしてJRuby使います。
コードがちょっと長めに見えますが、この例ではセットアップ部分が主なのと、わざと冗長に書いてある部分があるのでそのへんは差し引いてください。実用するために共通化とかすれば実際にはgetHelloSLSB().hello()の一行程度になるはずです。
require 'java' JBOSS_HOME="/home/nekop/eap6" require "#{JBOSS_HOME}/bin/client/jboss-client.jar" require "./example-as7-ejb.jar" java_import "java.util.Properties" java_import "javax.naming.Context" java_import "javax.naming.InitialContext" p = Properties.new() p.put("remote.connections", "default") p.put("remote.connection.default.port", "4447") p.put("remote.connection.default.host", "localhost") p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false") p.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming") p.put("org.jboss.ejb.client.scoped.context", true) initial_context = InitialContext.new(p) ejb_context = initial_context.lookup("ejb:") begin ear_name = "" war_name = "example-as7-ejb" ejb_name = "HelloSLSB" interface_name = "jp.programmers.examples.ejb3.slsb.Hello" bean = ejb_context.lookup("#{ear_name}/#{war_name}/#{ejb_name}!#{interface_name}") puts bean.hello("world") ensure begin ejb_context.close rescue # no-op end end
一番のポイントはejb_contextの取得とクローズです。このオブジェクトがこのサーバに対するEJBのクライアントコンテキストに対応しています。ejb_context.closeを呼び出すことによって、EJBクライアントのリソースが解放されるようになっています。