- - PR -
環境の違いによるリソースファイルの読み込み失敗
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-07-15 03:37
ちょっと、テクニカルなんですが、こんなことやってます。
Aというクラスでリソースを読み込みます。 A.class.getResourceAsStream("/a"); で、このクラスはa.jarにパッケージングされています。 /aというファイルはa.jarには含まれません。 Tomcat上で動くWebアプリケーションがあります。 WEB-INF/lib に 上記、a.jarを配置し、 WEB-INF/classes に aというファイルを置きます。 開発環境である tomcat-5.5.9 on Windows、Eclipseで動かした場合は このリソースファイルを見つけることができるのですが、 本番環境である tomcat-5.5.17 on Linuxで動かした場合は このリソースファイルを見つけることができません。 その他、環境の違いは、 開発環境は、Eclipseのプロジェクトをserver.xmlで 設定して、直接動かしていますが、 本番環境は、Webアプリケーションをwarにパッケージ ングして、webappsに配備します。 開発環境は、WEB-INF/libにa.jar、その他必要なjar を配備していますが、 本番環境は、とりあえず、$TOMCAT_HOME/shared/lib/ にa.jar、その他必要なjarを配備しています。 本番環境でもリソースファイルを見つけるには、 どのような設定が必要でしょうか? よろしくお願いいたします。 [ メッセージ編集済み 編集者: Jumpin' Jack Flash 編集日時 2006-07-15 03:37 ] | ||||||||
|
投稿日時: 2006-07-15 12:08
結論から言うと、本番環境でもa.jarをWEB-INF/libに置くか、
WEB-INF/classesやWEB-INF/libに置いた別のクラスを指定して getResourceAsStream()するようにしましょう。 A.class.getResourceAsStream()は、 A.class.getClassLoader().getResourceAsStream()と等価です。 つまり、Aをロードしたクラスローダにリソースの読み込みを行わせます。 ここで問題になるのが、複数のクラスローダの存在です。 Tomcatでのクラスローダは、以下のページに示すような階層化がされています。 http://www.jajakarta.org/tomcat/tomcat5.0/ja/docs/tomcat-docs/class-loader-howto.html 詳しい説明は上のページに譲りますが、 Aをshared/libに置くと、AのクラスローダはWebappXの親である Sharedクラスローダになるので、 A.class.getClassLoader().getResourceAsStream()では Sharedの子であるWebappXクラスローダが管理するリソースを 読み取ることができない、ということです。 AをWEB-INF/libに置けば、AのクラスローダはWebappXになり、 クラスローダがリソースを見つけられるようになります。 もしくは、WebappXがロードする他のクラスを使用してもいいでしょう。 | ||||||||
|
投稿日時: 2006-07-15 14:17
書いた後に、a.jarをWEB-INF/libに置いてみようと思い、 やってみたのですが、結果は同じでWEB-INF/classes下の リソースが読み込めませんでした。
こちらにつきましては、イメージ的に ・webappsX のクラスは sharedのクラスを知っているが ・shared のクラスは webappsX のクラスを知らない 気がするので、違和感があります。 (a.jarをshared/lib/ に置いた行為は、これに矛盾しますが) 申し訳ございませんが、ご紹介のページはまだナナメ読みした 程度なので、よく読んでみます。 取り急ぎ、ご報告までに。 | ||||||||
|
投稿日時: 2006-07-16 03:19
申し訳ございません、a.jarをWEB-INF/libに置いても
状況は変わらなかったと書きましたが、間違いでした。 WEB-INF/classes下のリソースが読み込めるようになりました。 ただ、a.jarをshared/libに置いても動くようにしたくて、 いろいろ試してみました。 ご紹介していただいたページも熟読しました。 A.class.getResourceAsStream("/a"); ではなく、 Thread.currentThread().getContextClassLoader() で WebAppXのClassLoaderを取得できますので、 このClassLoaderに対して.getResourceAsStream("/a"); とすれば、リソースを見つけられました。 WebAppXのClassLoader と A.classのインスタンスを Mapで管理し、複数のWebAppが動いている中でも それぞれのリソースを使い分けることができました。 この度は、親切なご対応、誠にありがとうございました。 |
1