<< 猫ページ | Home | 家のサーバにJBoss 5 CR1を入れてみた。 >>
PR: 転職    葬式    マンスリーマンション 神戸    北海道    環境    FX    不動産担保融資    桐ヶ谷斎場    海外旅行    専門学校   

JBoss5 CR1で、Sunのチュートリアルを動かす。

SunのJavaEEチュートリアルにある、EJB3のサンプル、converterを、JBoss5 CR1で動かしてみた。で、結論から言うと動かないわけなんだけど、原因を見てみると、EJBのルックアップで失敗している。JSFなら、インジェクションできるんだけど、JSPなんで、JNDIルックアップをしている。チュートリアルでは、

    InitialContext ic = new InitialContext();
    converter = (Converter)ic.lookup(Converter.class.getName());

という感じで、クラスのパッケージ名を含めた完全修飾名を渡すことで取得している。JBossでは、これだと見つからないと言われる。ここの名前は”アプリケーション名/EJB名/remote"という書式で指定する必要があるようだ(追記:nekopさんからの情報で、やはりJNDI名は仕様で規定されていないらしい)。

    InitialContext ic = new InitialContext();
    converter = (Converter)ic.lookup("converter/ConverterBean/remote");

先頭の"converter"は、EARファイルの名前から".ear"を除いたもの。ConverterBeanの部分はEJBの実装クラス名。これはよろしくないので、@Stateless(name = "XXX")として、抽象的な名前を指定してやるのが良いかと思われる。

で、これだけだと、Converterにはキャストできないというエラーが出る。どうも別のクラスローダで、Converterインターフェースを読んでしまうようだ(これはJBossのバグなのかもしれない これもnekopさんからの情報によると、チュートリアルが、EJBのjarを、Web moduleのWEB-INF/libに入れてしまっているせい。このあたりも現在の仕様では明確な規定が無いそうだ)。jndi.propertiesをWebアプリケーションのクラスパスに入れてやればok (これは、Web ModuleのWEB-INF/classes, libからEJBのインターフェースを除いてやれば不要)。

java.naming.factory.url.pkgs=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost

う〜む、このあたりの互換性が無いのは、問題なんじゃないだろうか。



Re: JBoss5 CR1で、Sunのチュートリアルを動かす。

JNDI名は仕様レベルで定義されていません。 ClassCastExceptionは、JBossがChild-firstのクラスローダを使用しており、EJBはEJB内の、WebアプリケーションからはWAR内のクラス定義を読んでしまい、かつCall-by-referenceでの呼び出しをしてしまうからです。WAR内から重複するクラスを外してパッケージングすれば動作します。Parent-firstだとCall-by-refでもそのまま呼べますが、EJBで利用しているライブラリと同じライブラリの別バージョンをWAR内で使えない問題があります。 もちろんCall-by-valueにすることでも、Parent-firstのクラスローダに変更することでも解決はできますが、それぞれ問題があるので、パッケージングをちょっといぢるだけで良いところに落ち着く設定がデフォルトになっています。 http://wiki.jboss.org/wiki/ClassLoadingOverview http://wiki.jboss.org/wiki/ClassLoadingConfiguration

Re: JBoss5 CR1で、Sunのチュートリアルを動かす。

ありがとうございます。なるほど、Web moduleからEJB呼ぶ時は、EJBのインターフェースをWEB-INF/libに入れなくても、見えるようになっているんですね。外してみたら、jndi.propertiesが無くても動作するようになりました。Glassfishでも問題無かったんで、チュートリアルの問題っぽいですね。
EJBのJNDI名は、やはり仕様には定義されていないのですか。ここは決めてくれないと、アプリケーションを作る側がつらいですね。あぁ、でもJSFでインジェクションが前提だから、重要視されていないのかな...

Re: JBoss5 CR1で、Sunのチュートリアルを動かす。

残念ながら、パッケージングもチュートリアルの問題というものではなく、同じく仕様ではかなり未定義なところです。

Re: JBoss5 CR1で、Sunのチュートリアルを動かす。

そうなんですか。そのあたりまで未定義だと、EARレベルでの可搬性の確保は不可能に近いですね。

コメント追加 トラックバック送信
このサイトの掲載内容は私自身の見解であり、必ずしもIBMの立場、戦略、意見を代表するものではありません。
日本アイ・ビー・エム 花井 志生 Since 1997.6.8