- PR -

サーブレットからJNI

1
投稿者投稿内容
h2
ベテラン
会議室デビュー日: 2004/12/23
投稿数: 58
投稿日時: 2005-01-15 03:41
いつもお世話になっております.
サーブレットのクラスからJNIを用いたクラスをインスタンス化して呼んでいるのですが,UnsatisfiedLinkError となってしまいます.
過去ログの情報をもとに LD_LIBRARY_PATH に so ファイルを配置し,ローカルで実行する場合には正しく動作していることを確認しました.
サーブレットのクラスとJNIを利用したクラスは同一パッケージなので,ファイルは以下のように配置しています.

エントリポイント
  WEB-INF
    classes
      パッケージ
        サーブレットのクラス
        JNIを利用したクラス


動作しない原因として考えられるものはございますでしょうか?
お力をお貸し頂けると幸いです.

[ メッセージ編集済み 編集者: h2 編集日時 2005-01-15 03:41 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-15 04:16
原因として考えられるのは

・パスにネイティブライブラリが通っていない
->起動スクリプトを確認しましょう
・複数のクラスローダで同一のライブラリをロードしようと試みている
->WEB-INF/classes に配置するのではなくシステムクラスパスに通すのが無難です

といったところでしょうか。

以下のスレッドも参考になるかと思います。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=17888&forum=12
h2
ベテラン
会議室デビュー日: 2004/12/23
投稿数: 58
投稿日時: 2005-01-15 06:01
インギさん いつも本当にお世話になっております.

ご指摘にあるとおり,WEB-INF/classes に配置するのではなく,クラスファイルをjar化して /usr/local/myclass を作成し,jarファイルを設置後,CLASSPATH に追加してみました.ローカルでクラスのコンパイルは通るようになったのですが,サーブレットとしてはうまく動かないので,WEB-INF/lib を作成した,その下にjarファイルを設置したところうまくいきました.
TomcatからみたCLASSPATHはローカルのCLASSPATHと別物なのでしょうか?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-01-15 07:08
>インギさん いつも本当にお世話になっております.
いえいえ。お役に立てれば幸いです。

で、libに配置したら解決した? とのことですが WEB-INF/classes と WEB-INF/lib は jar にパッケージするかしないかの違いで意味はほぼ変わりません。
#クラスが重複している場合は WEB-INF/classes が優先されます
WEB-INF/lib に配置することで動くようになったのであれば classes に配置していたときに配置するパッケージの階層がまちがっていた可能性があります。
#jar にパッケージしたまま classes に配置していたわけじゃないですよね?

>TomcatからみたCLASSPATHはローカルのCLASSPATHと別物なのでしょうか?
Tomcat の起動スクリプトを見ないとわかりませんが、恐らく明示的に -cp または -classpath オプションでクラスパスを指定しています。
よって CLASSPATH 環境変数に設定しているパスは尊重されない「かも」しれません。
いずれにせよトラブルを避けるためにも JNI を利用するライブラリは(WEB-INF/classes,lib に配置するのではなく)明示的にクラスパスに通すことをお勧めします。
詳しくは先に挙げたスレッドでも説明していますが、WEB-INF/lib とか WEB-INF/classes に配置していると特定の条件で UnsatisfiedLinkError が発生する可能性がありますので。

[ メッセージ編集済み 編集者: インギ 編集日時 2005-01-15 07:10 ]
h2
ベテラン
会議室デビュー日: 2004/12/23
投稿数: 58
投稿日時: 2005-01-15 07:21
>WEB-INF/lib に配置することで動くようになったのであれば classes に配置していたときに配置するパッケージの階層がまちがっていた可能性があります。
>#jar にパッケージしたまま classes に配置していたわけじゃないですよね?

はい,libに置くためにjar化しました.
パッケージの構造を維持していたつもりだったのですが,きちんと確認すればよかったと思っております.


>Tomcat の起動スクリプトを見ないとわかりませんが、恐らく明示的に -cp または -classpath オプションでクラスパスを指定しています。
>よって CLASSPATH 環境変数に設定しているパスは尊重されない「かも」しれません。
いちど Tomcat の起動スクリプトをよく読んで,明示的にクラスパスを追加するように指定し,JNIのクラスもローカルの場合と同じ所から参照できるように変更してみます.

本当にありがとうございます.

h2
ベテラン
会議室デビュー日: 2004/12/23
投稿数: 58
投稿日時: 2005-01-15 10:18
Tomcat の startup.sh から呼ばれている catalina.sh の Add on extra jar files to CLASSPATH というセクションを編集することで,明示的にクラスパスを追加することができました.

インギさん,有益な情報をありがとうございました.
1

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