URLClassLoaderに与えるJarファイルのURLの書き方
URLClassLoaderの引数として与えるJarファイルのURLの書き方としては、
- file:[Jarへのファイルパス]
- 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)
index2.htmlが存在しない場合
index2.htmlが存在する場合
前提(2)
index.htmlが存在しない場合
index.htmlが存在する場合
まとめ
- WebLogicでは、welcome-fileで指定したファイル(指定がない場合はindex.html)のありなしに関わらず、コンテキストルートへのリクエストはServletフィルタに処理が渡りません。
- Tomcatでは、webcome-fileで指定したファイル(指定がない場合はindex.html)がある場合は、コンテキストルートへのリクエストはServletフィルタに処理が渡されません。welcome-fileで指定したファイルがない場合は、Servletフィルタに処理が渡ります。
よって、WebLogic上でYmirを動作させた場合、コンテキストルートへのリクエストに対応するPageクラス(_RootPage)を自動生成することはできません。また_RootPageクラスで何らかの処理を行なうこともできません。
なおTomcat+Ymirで_RootPageクラスを自動生成したい場合や_RootPageクラスで何らかの処理を行ないたい場合は、web.xmlのwelcome-fileに存在しないファイルを指定すれば良いです(そのためViliで作成されるYmirプロジェクトのweb.xmlには「
サンプルアプリケーションをT2プロジェクトから分離します
今まではT2自体とT2のサンプルアプリケーションを同時期にリリースしていたのですが、コミッタ間で協議した結果、これらの開発サイクルって違うよねという話になり、今後は別々のサイクルでリリースすることになりました。
この件に関して詳しく知りたい方はid:shot6の記事「サンプルアプリケーションをT2プロジェクトから分離します」を見て下さい。
T2のサンプル作ってみたよ、という方はぜひこの機会にサンプルアプリケーションプロジェクトに参加していただければと思います。
内部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言語仕様に書いてあるんだろうなぁ…。