nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

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クライアントコンテキスト管理にJBossAPIを利用する必要があったのですが、JBoss EAP 6.1からはJNDIのAPIからEJBクライアントコンテキストの管理ができ、JBossAPIを利用する必要はなくなっています。

サーバサイドは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クライアントのリソースが解放されるようになっています。