はじめに

あるサービスがどのように処理されるかを調べる場合、様々な設定がどのような値になっているかを調べる必要があります。そこで、コンテナのmainメソッドから読み進めることでどこでどのような値が設定されるのかを読解することにします。

org.globus.wsrf.container.ServiceContainer

globus-start-containerにより起動されるクラスはorg.globus.wsrf.container.ServiceContainerです。というわけでServiceContainerのmainメソッドを見ていきましょう。簡単のため、セキュアコンテナではない(引数として-nosecを指定)とします。同クラスのcreateContainerメソッドを呼び出し、ServiceContainerオブジェクトを作成しているようです。

createContainerメソッドに進む前にmainメソッドの続きを見てみると、

container.waitForInit();
container.waitForStop();

となっており、それぞれ、ServiceDispatcherオブジェクトの同名メソッドに処理が委譲されています。このことから、コンテナのメイン処理はServiceDispatcherオブジェクトが行っていると推測されます。

createContainerメソッドでは渡されたプロパティからどのクラスをServiceContainerオブジェクトとして生成するかを取得*1し、オブジェクトの生成を行っています。デフォルトではServiceContainerクラスのインスタンスが生成されるようです。コンストラクタではstartメソッドを呼び出しているので、startメソッドの読解に進みましょう。

startメソッドではServiceDispatcherオブジェクトの生成、初期化、起動が行われています。リファレンスカウントを増やしたり、ServiceContainerをCollectionやHashtableに登録したりしていますが通常はServiceContainerは一つだと思われるので無視していいでしょう。それでは読解対象をServiceDispatcherクラスに移します。

org.globus.wsrf.container.ServiceDispatcher

コンストラクタにて、まず設定ファイル名を決定していますがプロパティは設定されていないはずなのでデフォルトのserver-config.wsddでしょう。次に設定ファイルのベースディレクトリ($GLOBUS_LOCATION/etc)を設定してAxisServerを生成しています。AxisServer(のスーパークラスのAxisEngine)のコンストラクタ(が呼び出しているinitメソッド)では引数として渡されたEngineConfiguration(今回のケースではDirProvider)にコールバックしています。DirProviderオブジェクトはベースディレクトリ以下の個々のディレクトリ(GT4ではサービスの設定はサービスごとにディレクトリに分けられて置かれています)についてserver-config.wsddの読み込み、デプロイを行っているようです。個々のサービスの読み込みについては素直にaxisそのままなようです。

さて、次にinitメソッドを眺めてみましょう。いろいろやっていますが重要そうなのはServiceManager.startメソッドのようです。ServiceDispatcher.startメソッドを先に見てみるとなんとなく予想できるようにスレッドを作成してソケットの待ち受けを開始しています。リクエストがどう処理されるかはGT4のリクエスト処理方法を読む?で読むことにして注目をServiceManagerクラスに移しましょう。

org.globus.wsrf.container.ServiceManager

startメソッドを見るとstartメソッドでは次の2つの処理を行っていることがわかります。

  1. JNDIの初期化
  2. loadOnStartup=trueとなっているサービスの初期化

ではJNDIの初期化を見ていきましょう。

org.globus.wsrf.jndi.JNDIUtils.initializeDir

JNDIの初期化はorg.globus.wsrf.jndi.JNDIUtils.initializeDirメソッドで行われています。まず、同クラスのinitJNDIメソッドが呼び出されています。

JNDIの設定はされていないはずですのでSystem.getProperty()の結果はnullだとします。initJNDIメソッドではURL_PKG_PREFIXESをorg.apache.namingに、INITIAL_CONTEXT_FACTORYをorg.apache.naming.java.javaURLContextFactoryに設定するようです。INITIAL_CONTEXT_FACTORYを設定はしていますが、initialContextFactoryBuilderは設定してないのでlookupした場合改めてjavaURLContextFactoryが作成されて使われる気がします。JNDIのlookupは再帰的過ぎて迷子になってしまったのですが・・・、最終的にorg.apache.naming.NamingContextが使われるということでいいんでしょうか?

次に各サービスについてjndi-config.xml(デフォルト値)を処理しているようです。メソッド呼び出しをたどるとparseJNDIConfigメソッドでDigesterを使ってXMLからオブジェクトを作成し、JNDIにbindしているようです。Contextという名前はJNDIなのかGT4なのか紛らわしいのでもう少し気の利いた名前にして欲しかったですね:-)

ServiceManager.initializeService

それではサービスの初期化を見ていきます。個々の(loadOnStartup=trueな)サービスについてinitializeServiceメソッドが呼び出されています。余談ですが、MessageContext.serviceHandlerっていつの間に設定されたんだ!?と調べたらsetTargetServiceメソッドを呼び出すと設定されるんですね。

セキュア機能は使っていないのでsubjectはnullとなるはずです。ServiceManager.InitPrivilegedAction.initializeメソッドを読むとJNDIからサービスに対するResourceHomeオブジェクトを取得しています。JNDIにはReferenceとして登録しているため、bindの時点ではResourceHomeオブジェクトはまだ作られておらず初めて取得した時点で構築されるようです。その際、サービスのhomeリソースのfactoryパラメータで指定した値(通常、org.globus.wsrf.jndi.BeanFactory)が使われるようです。

おわりに

今回ソースを読む際にEclipseのシンボル宣言位置検索機能を利用してみました。なかなか便利ですが個々のjarについてソースがどこにあるか指定しないといけません。今回の読解範囲では、

wsrf_core.jar
メイン
wsrf_tools.jar
jndi-config.xml解析部分
axis.jar
axis

のソースを設定する必要がありました。

読解の感想としてはGT4はまだ素直だがJNDIやaxisはインターフェースと抽象クラスを多用しているためすぐに迷子になってしまう、徹底的にインターフェースプログラミングなのも規模が大きくなってくると微妙だなぁと言ったところです。それではみなさんもよいコードリーディングを。


*1 セキュアコンテナの場合、org.globus.wsrf.container.GSIServiceContainerが設定されます

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS