URLClassLoaderに与えるJarファイルのURLの書き方

URLClassLoaderの引数として与えるJarファイルのURLの書き方としては、

  1. file:[Jarへのファイルパス]
  2. jar:file:[Jarへのファイルパス]!/

の2通りが可能ですが、実は挙動が異なります。

クラスのロードやリソースの取得では同じ挙動をするのですが、ディレクトリリソースを取得してみると、
1の場合は取得できるのに対し、2では取得できません。

例えば

ClassLoader cl = new URLClassLoader(new URL[]{ new URL("file:/C:/s2-framework-2.4.20.jar") });
URL url = cl.getResource("org/seasar/framework");

とすると、urlは「jar:file:/C:/s2-framework-2.4.20.jar!/org/seasar/framework」となりますが、

ClassLoader cl = new URLClassLoader(new URL[]{ new URL("jar:file:/C:/s2-framework-2.4.20.jar!/") });
URL url = cl.getResource("org/seasar/framework");

とすると、urlはnullになります。

調べてみたところ、この挙動はSun JDK1.4、1.5、1.6で同様でした。

というわけで、JarファイルのURLを指定するときには「"jar:"+ファイルリソースのURL+"!/"」形式は避けたほうがよさそうです。

コンテキストルートへのリクエストの扱いの違い

Servletフィルタのurl-patternを「/*」にしている場合のコンテキストルートへのリクエストの扱いに違いがあることがわかったのでメモしておきます。

前提(1)

  • WebLogic Server 11gR1とTomcat6.0.20で検証
  • web.xmlにて、
    • Servletフィルタのurl-patternとして「/*」を指定
    • welcome-fileとして「index2.html」を指定
  • コンテキストルート「/context/」にリクエストを送信

index2.htmlが存在しない場合

  • WebLogicでは、Servletフィルタに処理が渡らずコンテナによってindex2.htmlにリダイレクトされます。リダイレクト後にServletフィルタに処理が渡ります。
  • Tomcatでは、Servletフィルタに処理が渡ります。

index2.htmlが存在する場合

  • WebLogicTomcatともに、Servletフィルタに処理が渡らずコンテナによってindex2.htmlにリダイレクトされます。リダイレクト後にServletフィルタに処理が渡ります。

前提(2)

  • WebLogic Server 11gR1とTomcat6.0.20で検証
  • web.xmlにて、
    • Servletフィルタのurl-patternとして「/*」を指定
    • welcome-fileを指定しない
  • コンテキストルート「/context/」にリクエストを送信

index.htmlが存在しない場合

  • WebLogicでは、Servletフィルタに処理が渡らずコンテナによってindex.htmlにリダイレクトされます。リダイレクト後にServletフィルタに処理が渡ります。
  • Tomcatでは、Servletフィルタに処理が渡ります。

index.htmlが存在する場合

  • WebLogicTomcatともに、Servletフィルタに処理が渡らずコンテナによってindex.htmlにリダイレクトされます。リダイレクト後にServletフィルタに処理が渡ります。

まとめ

  • WebLogicでは、welcome-fileで指定したファイル(指定がない場合はindex.html)のありなしに関わらず、コンテキストルートへのリクエストはServletフィルタに処理が渡りません。
  • Tomcatでは、webcome-fileで指定したファイル(指定がない場合はindex.html)がある場合は、コンテキストルートへのリクエストはServletフィルタに処理が渡されません。welcome-fileで指定したファイルがない場合は、Servletフィルタに処理が渡ります。

よって、WebLogic上でYmirを動作させた場合、コンテキストルートへのリクエストに対応するPageクラス(_RootPage)を自動生成することはできません。また_RootPageクラスで何らかの処理を行なうこともできません。

なおTomcatYmirで_RootPageクラスを自動生成したい場合や_RootPageクラスで何らかの処理を行ないたい場合は、web.xmlのwelcome-fileに存在しないファイルを指定すれば良いです(そのためViliで作成されるYmirプロジェクトのweb.xmlには「__dummy__.html」と書いてあります)。

Eclipse3.5.1での開発

最近ようやく時間ができてきてOSS活動に時間が取れるようになってきたので、手始めにYmirの開発環境をEclipse3.5系で構築してみました。(今まではEclipse3.3系で頑張ってました)

結論から言うと、特に問題なく構築できました。その内容を踏まえて、Ymirのサイト上で公開している環境構築手順のページもEclipse3.5系ベースに書き直しました。

http://ymir.seasar.org/docs/1.0.x/user/setUp

これからYmirを使った開発を始める方、今まで古いEclipseで開発していたけれどEclipse3.5系に環境を移したい方はぜひ見てみて下さい。

サンプルアプリケーションをT2プロジェクトから分離します

今まではT2自体とT2のサンプルアプリケーションを同時期にリリースしていたのですが、コミッタ間で協議した結果、これらの開発サイクルって違うよねという話になり、今後は別々のサイクルでリリースすることになりました。

この件に関して詳しく知りたい方はid:shot6の記事「サンプルアプリケーションをT2プロジェクトから分離します」を見て下さい。

T2のサンプル作ってみたよ、という方はぜひこの機会にサンプルアプリケーションプロジェクトに参加していただければと思います。

DBFlute-0.9.6-1フラグメントをリリースしました

DBFlute-0.9.6.4がリリースされましたので、Ymir用のDBFluteフラグメントでDBFlute-0.9.6.4をインストールできるようにしました。

DBFluteフラグメントのバージョンは0.9.6-1です。

新規Viliプロジェクトウィザードから「Ymir+DBFlute」プロジェクトを選択するだけで、自動的にこのフラグメントがダウンロードされて使用されます。

内部enumはstatic扱い

あるクラスCに内部enum Eを定義する場合、staticキーワードをつけるべきだろうか?

enumはその性質上staticと扱われないといろいろ不都合が生じるため、内部enumを作る場合にはstaticにしないといけない気がするが、ではstaticキーワードをつけないとどうなるのだろうか。

public class C {
    public enum E {};
}

Eが持つコンストラクタを調べてみる。

for (Constructor<?> c : E.class.getDeclaredConstructors()) {
    System.out.println(c);
}

すると以下のようになる。

public C$E(java.lang.String,int)

staticでない内部クラスは第一引数として親クラスを受け取るようなコンストラクタを持つが、staticキーワードをつけないで内部enumを定義すると、そのようなコンストラクタを持たないことが分かる。すなわち、

内部enumはstaticキーワードをつけなくてもstaticとして定義される

ということのようだ。

実際、staticキーワードをつけて内部enumを定義してみると、

public class C {
    public static enum StaticE {};
}
for (Constructor<?> c : StaticE.class.getDeclaredConstructors()) {
    System.out.println(c);
}

以下のようにstaticキーワードをつけなかった場合と同じ結果になる。

public C$StaticE(java.lang.String,int)

追伸:このあたりのことってきっとJava言語仕様に書いてあるんだろうなぁ…。

DBFlute-0.9.6フラグメントをリリースしました

DBFlute-0.9.6がリリースされましたので、Ymir用のDBFluteフラグメントでDBFlute-0.9.6をインストールできるようにしました。

なお、このフラグメントを使用するにはVili-0.3.3系が必要になります。

新規Viliプロジェクトウィザードから「Ymir+DBFlute」プロジェクトを選択するだけで、自動的にこのフラグメントがダウンロードされて使用されます。

ViliとDBFluteフラグメントを使うと簡単にYmir+DBFluteプロジェクトを作成することができますので、使ったことのない方はぜひ試してみて下さい。