Tomcat6.07β

java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
         : 略

ava.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
         : 略

javax.servletパッケージのクラスがClassNotFoundExceptionとなってしまう原因が解った。恥ずかしい位に初歩的なので書きたくないのだが、書かない訳にはいかないだろう。

同例外が発生していたのは、Webアプリケーションから参照されていた自作のサーブレットフィルタとコンテキストリスナだったのだが、これらのクラスはコンテキストのWEB-INF/classesに配置してあるのではなく、グローバルなクラスパス(CLASSPATH変数)に追加した外部パスである。(catalina.sh(bat)はCLASSPATHをリセットするので、setclasspath.sh(bat)に自ら追加した)

Tomcatユーザの諸兄であれば、ここまで書いたらもう例外の原因が想像できたことと思う。そう、追加した自作フィルタ/リスナクラスをロードしたクラスローダとservlet.jarをロードするクラスローダの階層が違う。更に自作クラスをロードするクラスローダの方が上位に当たるため、自分又はそれより上位のクラスローダは永久にjavax.servletパッケージのクラスを見つけることはできないのだ。

いや〜お恥ずかしい。サーブレットコンテナを弄るのは久しぶりだったのでいろいろと基本を忘れているようでぼけぼけだ。

自作のクラスをWEB-INF/classesかWEB-INF/libにコピーすれば良いだけなのだが、できればそうしたくないんだよな。UNIXならばリンク張れば良いのだが、Windows(XP)だと駄目だ(ジャンクションは役に立たないだろう)