Saturday, September 24, 2011

springの設定ファイルをWEB-INF直下に置くとテストが難しくなる

Spring + Struts あるいはSpring + SpringMVCといった組み合わせでWebアプリケーションを作る場合、
src/main/webapp/WEB-INF/applicationContext.xml
のような位置にspringのbean定義ファイルをつくる例が多いようです。実際、巷の書籍やIT系サイトの記事などでもそのようなサンプルがよく公開されています。

しかし、この配置方法には実は大きな問題があります。JUnitなどのテストケースを実行するとき、その設定ファイルをロードできません。なぜならWEB-INFの直下はクラスパスではないからです。 このスレッドでもほぼ同じ問題について議論されていますが、このときは結論はでていなかったようです。 結局、似たような設定ファイルをsrc/test/resources配下等に置いて二重管理するといった、気の進まない方法に頼ることになってしまいます。

eclipse上でsrc/main/resources/applicationContext.xml のようなビルドパスの通っている位置に移動させたうえで、web.xmlのほうには
    
        org.springframework.web.context.ContextLoaderListener
    
    
        contextConfigLocation
        classpath:mainContextConfig.xml
    
のようにclasspath:記法で書いておけば、クラスパス配下の設定ファイルをロードしてくれる(実体はWEB-INF/classes/mainContextConfig.xmlのようになる)。。。 はずなのですが、そうはとんやかです。

詳細は不明ですが、ContextLoaderListenerは強制的にWEB-INF/直下の設定ファイルを探しに行ってしまいます。 結果、FileNotFoundExceptionを吐いてWebアプリが起動しません。 これを防ぐため、たとえば
    
        contextConfigLocation
        WEB-INF/applicationContext.xml, classpath:mainContextConfig.xml
    
のように書いておき、applicationContext.xmlには<beans><!-- dummy! --></beans>のような無設定のダミーを仕込んで、本来の設定をすべてclasspath:mainContextConfig.xmlのほうに書いておくことで対応できます。