- PR -

環境の違いによるリソースファイルの読み込み失敗

1
投稿者投稿内容
Jumpin'' Jack Flash
大ベテラン
会議室デビュー日: 2006/01/24
投稿数: 198
投稿日時: 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 ]
koe
大ベテラン
会議室デビュー日: 2003/07/13
投稿数: 198
投稿日時: 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がロードする他のクラスを使用してもいいでしょう。
Jumpin'' Jack Flash
大ベテラン
会議室デビュー日: 2006/01/24
投稿数: 198
投稿日時: 2006-07-15 14:17
引用:

koeさんの書き込み (2006-07-15 12:08) より:
結論から言うと、本番環境でもa.jarをWEB-INF/libに置くか、



書いた後に、a.jarをWEB-INF/libに置いてみようと思い、
やってみたのですが、結果は同じでWEB-INF/classes下の
リソースが読み込めませんでした。

引用:

WEB-INF/classesやWEB-INF/libに置いた別のクラスを指定して



こちらにつきましては、イメージ的に
・webappsX のクラスは sharedのクラスを知っているが
・shared のクラスは webappsX のクラスを知らない
気がするので、違和感があります。
(a.jarをshared/lib/ に置いた行為は、これに矛盾しますが)

申し訳ございませんが、ご紹介のページはまだナナメ読みした
程度なので、よく読んでみます。

取り急ぎ、ご報告までに。
Jumpin'' Jack Flash
大ベテラン
会議室デビュー日: 2006/01/24
投稿数: 198
投稿日時: 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

スキルアップ/キャリアアップ(JOB@IT)