Embedded-Jettyでのクラスアクセス



※Jettyに関する全投稿は/tag/jettyにあるので参照されたい

JettyをEmbedded(組み込み)で使用し、warファイルをホスティングした場合に、そのコンテナ側(ホスト側)のコードとwar側のコードはどのように協調できるのだろうか?つまり、疑問はこうだ。

  • war側からコンテナ側のクラスが利用できるのか?これはTomcat等を見てもわかるように利用可能なのだが、しかし、「同じもの」としてロードされるのか?簡単に言えば、コンテナ側で設定したstatic変数値をwar側からも使用可能なのか?
  • 逆にコンテナ側からwar側のコードを直接利用することができるのか?上の項目とは逆で、war側で設定したstatic変数値をコンテナ側からも利用することができるのか?

サンプルプログラム

これを確かめるためのサンプルを作成した。https://github.com/ysugimura/jettySample1にある。

これはEclipse用のプログラムであり、build.gradleに対し、「gradle eclipse」とすれば、Eclipse用の.project, .classpathを自動設定して、Eclipse上でのテストが可能になる。

特に重要なのは、srcフォルダが分離しており、それぞれのsrcフォルダから生成される.classファイルの出力先を分離していることだ。

以下のように、コンテナ側はbinに、その他はwara/WEB-INF/classes, warb/WEB-INF/classesになる。

ここでは二つのwarをデプロイしてみるために、それぞれwara, warbという名前にしている。

実行

Mainを起動して、「localhost:8080/a/servlet1」「localhost:8080/a/servlet2」「localhost:8080/b/servlet3」にアクセスしてみる。

クラスローダ

クラスローダがどうなっているかも表示させているのだが、以下になる(Jettyからの警告は削除済)

Main:sun.misc.Launcher$AppClassLoader@2a139a55 sun.misc.Launcher$ExtClassLoader@511d50c0 
Servlet1:WebAppClassLoader=1856426318@6ea6d14e sun.misc.Launcher$AppClassLoader@2a139a55 sun.misc.Launcher$ExtClassLoader@511d50c0 
Servlet2:WebAppClassLoader=1856426318@6ea6d14e sun.misc.Launcher$AppClassLoader@2a139a55 sun.misc.Launcher$ExtClassLoader@511d50c0 
Servlet3:WebAppClassLoader=1917513796@724af044 sun.misc.Launcher$AppClassLoader@2a139a55 sun.misc.Launcher$ExtClassLoader@511d50c0 

つまり、コンテナ側のクラスローダがあり、warごとにその子のクラスローダが使われている。wara,warbのクラスローダは別になっている。

コンテナ側への変数のアクセス

次にコンテナ側にあるクラスのstatic変数に、コンテナが設定したstatic値をwara側からアクセスできるかだが、これはアクセス可能だ。「localhost:8080/a/servlet1」の結果が、以下となり、コンテナ側で設定した123という値が表示される。

war側へのコンテナ側のアクセス

次に「localhost:8080/a/servlet2」の結果なのだが、これはwara側にあるクラスのstatic値をwara側で設定し、コンテナ側からアクセスさせるものだが、結果は以下になる。

コンテナ側からはwar側のクラスを利用できるものの、war側で使用している「モノ」とは異なる。別途クラスがロードされてしまう。

もちろん、前述したクラスローダの階層構造を考えれば、この結果は当然なのだが。

※servlet3はクラスローダ比較のために作成したもので有用な中身は無い。

結論と参考文献

Tomcatの場合の参考文献として以下があげられる。

ただし、今回確認したかったことは、Jettyを組み込みとして使用した場合に、ホストされたwarファイルは組み込みホスト側(コンテナ側)とのデータのやりとりができるのか?ということで、少々方向性が違う。

わざわざ組み込みという形態にするのはそれなりの理由があるからだ。今回のテストで「十分に使える」ものであることは理解できた。